Código de muestra de estructura de datos y su explicación: pila y cola

Pilas y colas

apilarapilar

último en entrar primero en salir

La definición de estructura y operaciones básicas de la pila.

#define MaxSize 50
typedef struct {
    
    
	int data[MaxSize];//栈中存放数据类型为整型
	int top;//栈顶指针
}Stack;

inicialización

Al inicializar aquí, el puntero superior de la pila apunta a -1 y algunos apuntan a 0, por lo que el código para push y pop posteriores es ligeramente diferente

void InitStack(Stack& S) {
    
    //初始化栈
	S.top = -1;
}

Compruebe si la pila está vacía

int IsEmpty(Stack S) {
    
    //判断栈是否为空
	if (S.top == -1)
		return 1;
	else
		return 0;
}

operación de empuje

  1. Dado que el puntero superior de la pila apunta inicialmente a -1, primero es necesario cambiar el puntero superior de la pila y luego empujarlo hacia la pila;
  2. Y cuando MaxSize es 50, el campo de datos está en datos[0]~datos[49], así que aquí está S.top == MaxSize - 1 significa que la pila está llena;
  3. Las líneas 4-5 se pueden combinar como S.data[++S.top]=x.
int Push(Stack& S, int x) {
    
    //压栈操作
	if (S.top == MaxSize - 1)//若栈满则无法压栈
		return 0;
	S.top++;
	S.data[S.top] = x;
	return 1;
}

operación pop

  1. Aquí, el elemento extraído es recibido por x, se recibe primero cuando se extrae y luego el puntero superior de la pila disminuye
  2. Las líneas 4-5 se pueden combinar como x=S.data[++S.top]
int Pop(Stack& S, int& x) {
    
    //出栈操作
	if (S.top == -1)//若栈空则无法出栈
		return 0;
	x = S.data[S.top];
	S.top--;
	return 1;
}

leer el elemento superior de la pila

​ Aquí, los elementos que salieron de la pila son recibidos por x

int GetTop(Stack S, int& x) {
    
    //读取栈顶元素
	if (S.top == -1)//若栈空则无栈顶元素
		return 0;
	x = S.data[S.top];
	return 1;
}

Por supuesto, lo anterior es una pila secuencial, y también hay una pila en cadena, que es similar a una lista de un solo enlace. El nodo principal es el encabezado de la pila y el otro lado es la parte inferior de la pila. Ambos apilados y el apilamiento se realiza en el nodo principal, lo cual es conveniente para la operación.

01 Hay una lista L enlazada individualmente con un nodo principal. La estructura del nodo se compone de dos campos, datos y siguiente, entre los cuales el campo de datos es de tipo carácter. Intente diseñar un algoritmo para juzgar si los n caracteres de la lista vinculada son centrosimétricos. Por ejemplo, xyx y xyyx son centrosimétricos.
  1. Para juzgar si este tipo es centralmente simétrico, generalmente se utiliza la pila;
  2. En esta pregunta, se divide en dos partes, la parte delantera y trasera, y la primera mitad se empuja a la pila a su vez. Cuando se llega a la segunda mitad, se compara con los elementos que salen de la pila. Durante la comparación, el puntero en la parte superior de la pila se mueve. movimiento del puntero transversal;
  3. propenso a erroresDespués de que el bucle for se empuja a la pila, la posición de i es la posición después del elemento superior de la pila, y se requiere i- para devolverlo a la posición superior de la pila.
  4. Cuando el número de nodos es par, se procesará normalmente; cuando el número es impar, el elemento del medio no se insertará en la pila y el puntero transversal irá un paso más, sin pasar por el elemento del medio;
int central_symmetry(LinkList L, int n) {
    
    
	char S[n / 2];//定义字符型数组来作为一个栈
	int i;//定义栈顶指针
	LNode* p = L->next;//定义遍历指针
    //对称轴左边字符依次入栈
	for (i = 0; i < n / 2; i++) {
    
    
		S[i] = p->data;
		p = p->next;
	}
	i--;//变量 i 返回栈顶位置
	if (n % 2 == 1) {
    
    //若字符数为奇数则 p 向后遍历一步,因为最中间字符不需考虑
		p = p->next;
	}
	while (p != NULL) {
    
    //对称轴右边字符依次与栈顶元素比对
		if (p->data == S[i]) {
    
    //与栈顶元素相等则 p 继续遍历与下一出栈元素比较
			i--;//出栈
			p = p->next;//继续遍历
		}
		else//若不等,则说明 n 个字符不对称,直接返回 0
			return 0;//非中心对称
	}
	return 1;//若正常跳出循环,则证明 n 个字符对称,返回 1
}
02 Suponga que una expresión aritmética contiene dos tipos de paréntesis, paréntesis y corchetes, escriba un algoritmo para juzgar si los paréntesis en la expresión están emparejados, asumiendo que la expresión aritmética está almacenada en una matriz de caracteres y el carácter '\ 0' se utiliza como aritmética El terminador de la expresión.
  1. En esta pregunta, no se requieren operaciones para números y operadores.
  2. La instrucción de cambio se ejecuta secuencialmente de arriba a abajo, por lo que es necesario romper para saltar;
  3. Cuando encuentre un paréntesis derecho, primero debe determinar si la pila está vacía. Si está vacía, significa que no coincide;
  4. Si la pila está vacía después de completar el recorrido de la matriz, demuestra que todos los paréntesis izquierdos están emparejados correctamente.
int BracketsCheck(char a[]) {
    
    
	Stack S;
	InitStack(S);
	char x;
	for (int i = 0; a[i] != '\0'; i++) {
    
    
		switch (a[i]) {
    
    
			case'('://若数组元素为左括号,则压栈继续遍历
				push(S, a[i]);
				break;
			case'[':
				push(S, a[i]);
				break;
			case')'://若元素为右括号,则需考虑是否有左括号与之配对
				if (IsEmpty(S) {
    
    
					return 0;//若栈空,则说明无左括号与之配对
				}
				else {
    
    
					Pop(S, x);
					if (x != '(') {
    
    //若栈不为空,则判断栈顶元素与当前括号是否配对
						return 0;
					}
                    //配对上了
					break;
				}
			case']':
				if (IsEmpty(S)) {
    
    
					return 0;
				}
				else {
    
    
					Pop(S, x);
					if (x != '[') {
    
    
						return 0;
					}
					break;
				}
			default://若数组元素不是括号则直接继续遍历
				break;
		}
	}
	if (IsEmpty(S)) {
    
    //若数组遍历完成后栈为空,则证明所有左括号全部配对成功
		return 1;
	}
	else {
    
    //若栈不为空,则证明有左括号未配对
		retun 0;
	}
}
03 Las dos pilas S1 y S2 adoptan el método de pila secuencial y comparten un área de almacenamiento [0,...,MaxSize-1]. Para maximizar el uso del espacio y reducir la posibilidad de desbordamiento, el método de almacenamiento con el Se pueden usar la parte superior de la pila uno frente al otro y creciendo de frente. Intente diseñar y escribir la definición de esta pila y los algoritmos de operación de S1 y S2 relacionados con el apilamiento y la extracción.

​ Dos pilas requieren dos punteros superiores de la pila. La matriz superior se define aquí, uno superior [0] y otro superior [1]

#define MaxSize 50
typedef struct{
    
    
	int data[MaxSize];
	int top[2];//一个top[0],一个top[1]指针
}DStack;

inicialización

void InitDStack(DStack& S) {
    
    
	S.top[0] = -1;//初始化 S1 栈顶指针
	S.top[1] = MaxSize;//初始化 S2 栈顶指针
}

pila

  1. Debido a que un espacio de almacenamiento tiene dos pilas, es necesario decir qué pila se va a insertar en la pila, y i se usa para distinguir qué pila;
  2. Aquí S [1] representa la pila inferior y S [2] representa la pila superior.
int push(int i, int x) {
    
    
	if (i < 0 || i>1) {
    
    
		return 0;//若 i 的输入不合法,则无法入栈
	}
	if (S.top[1] - S.top[0] == 1) {
    
    //若存储空间已满,则无法进行入栈操作
		return 0;
	}
	switch (i) {
    
    
		case 0:// S1 栈顶指针上移后入栈
			S.top[0]++;
			S.data[S.top[0]] = x;
			//S.data[++S.top[0]] = x;
			break;
		case 1:// S2 栈顶指针下移后入栈
			S.top[1]--;
			S.data[S.top[1]] = x;
			//S.data[--S.top[1]] = x;
			break;
	}
	return 1;
}

salir

int pop(int i, int& x) {
    
    
	if (i < 0 || i>1) {
    
    
		return 0;
	}
	if (S.top[0] == -1 || S.top[1] == MaxSize) {
    
    //空栈
		return 0;
	}
	switch (i) {
    
    
        case 0:
            x = S.data[S.top[0]];
            S.top[0]--;//下面的栈往下移
            //x = S.data[S.top[0]--];
            break;
        case 1:
            x = S.data[S.top[1]];
            S.top[1]++;//上面的栈顶指针往上移
            //x = S.data[S.top[1]++];
            break;
        }
	return 1;
}

Cola Cola

primero en entrar primero en salir

​ La definición de estructura de la cola y sus operaciones básicas.

#define MaxSize 50
typedef struct {
    
    
	int data[MaxSize];//队列中存放数据类型为整型
	int front, rear;//队首指针和队尾指针
}Queue;
void InitQueue(Queue& Q) {
    
    //初始化队列
	Q.front = 0;
	Q.rear = 0;
}
int IsEmpty(Queue Q) {
    
    //判断队列是否为空
	if (Q.front == Q.rear)//若队首指针和队尾指针指向同一位置,则队列为空
		return 1;
	else
		return 0;
}

Poner en cola y sacar de cola

Aquí, el puntero al final de la cola apunta a la siguiente posición del elemento. Para obtener más información, consulte Operaciones de poner y quitar la cola.

Al ingresar al equipo, es el puntero al final del equipo el que debe ser判断队满Q.trasero == Tamaño máximo

//顺序队列的入队和出队:
//这里队尾指针指向元素的后一个位置
int EnQueue(Queue& Q, int x) {
    
    //入队操作
	if (Q.rear == MaxSize)//若队满,则无法入队
		return 0;
	Q.data[Q.rear] = x;//变量 x 入队
	Q.rear++;//队尾指针后移
	return 1;//入队成功
}

Es el puntero del jefe del equipo que sale a pelear por la derecha, y necesita判断队空Q.delantero == Q.trasero

int DeQueue(Queue& Q, int& x) {
    
    //出队操作
	if (Q.front == Q.rear)//若队空,则无法出队
		return 0;
	x = Q.data[Q.front];//变量 x 接收出队元素
	Q.front++;//队首指针后移
	return 1;//出队成功
}

cola circular

Debido a que Q.front == Q.rear juzgó que el equipo estaba vacío antes, si se repite, significa tanto vacío como lleno, por lo que es posible, por lo que 牺牲一个空间Q.front == Q.rear solo se puede usar para juzgar vacío.

Vacío :Q.delantero == Q.trasero

Veredicto completo :(Q.trasero + 1) % MaxSize == Q.frontal(Si la parte trasera se mueve hacia atrás, una es la delantera, significa que está llena)

Tanto el puntero de cola como el puntero de cabeza deben moverse hacia atrás+1取余

//循环队列的入队和出队:(牺牲一个存储空间)
int EnQueue(Queue& Q, int x) {
    
    //入队操作
	if ((Q.rear + 1) % MaxSize == Q.front)//若队满,则无法入队
		return 0;
	Q.data[Q.rear] = x;//变量 x 入队
	Q.rear = (Q.rear + 1) % MaxSize;//队尾指针后移
	return 1;//入队成功
}
int DeQueue(Queue& Q, int& x) {
    
    //出队操作
	if (Q.front == Q.rear)//若队空,则无法出队
		return 0;
	x = Q.data[Q.front];//变量 x 接收出队元素
	Q.front = (Q.front + 1) % MaxSize;//队首指针后移
	return 1;//出队成功
}
04 Si desea que se utilicen todos los elementos de la cola circular, debe establecer una etiqueta de campo de marca y usar el valor de la etiqueta como 0 o 1 para distinguir que el estado de la cola es "vacío" cuando el encabezado de la cola El puntero frontal y el puntero trasero de la cola son los mismos. Aún están "llenos". Intente escribir algoritmos de puesta en cola y retirada de cola correspondientes a esta estructura.
  1. En la cola circular, Q.front == Q.rear originalmente podía juzgar si la cola estaba vacía o llena, por lo que se sacrificaba un espacio arriba para un procesamiento especial;
  2. Esta pregunta juzga si el equipo está vacío o lleno configurando el campo de bandera;
  3. Aquí es necesario juzgar que el equipo está lleno solo al ingresar al equipo, por lo que la etiqueta se vuelve 1 después de cada entrada; es necesario juzgar que el equipo está vacío solo al salir del equipo, por lo que la etiqueta se vuelve 0 después de cada salida equipo, porque el equipo está vacío El juicio de Q.front == Q.rear debe juzgarse cuando el equipo está lleno. Por lo tanto, cuando los punteros de la cabeza y la cola de la cola no están en el mismo lugar, esto No se ingresará el juicio. La etiqueta debe establecerse en 0 inicialmente.
  4. Q.front == Q.rear && Q.tag == 1 y Q.front == Q.rear && Q.tag == 0 son muy fuertes, y ambos requieren que se cumplan dos condiciones al mismo tiempo
typedef struct {
    
    
	int data[MaxSize];
	int front, rear;
	int tag;
}Queue;
void InitQueue(Queue& Q) {
    
    //初始化队列
	Q.front = 0;
	Q.rear = 0;
    Q.tag = 0;
}
int EnQueue(Queue& Q, int x) {
    
    
	if (Q.front == Q.rear && Q.tag == 1) {
    
    //若队满,则无法进行入队操作
		return 0;
	}
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;//队尾指针后移
	Q.tag = 1;//入队后可能会出现队满的情况,所以将 tag 标志域置为 1
	return 1;
}
int DeQueue(Queue& Q, int& x) {
    
    
	if (Q.front == Q.rear && Q.tag == 0) {
    
    
		return 0;//队空
	}
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	Q.tag == 0;//出队后可能会出现队空的情况,所以将 tag 标志域置为 0
	return 1;
}
05 Q es una cola y S es una pila vacía, que realiza el algoritmo de revertir los elementos en la cola.
  1. La cola es el primero en entrar, el primero en salir y la pila es el último en entrar, primero en salir. Los elementos de la cola deben invertirse, de modo que los elementos de la cola se puedan sacar de la cola de la pila uno por uno. Cuando la cola está vacía, luego salga e ingrese a la cola para lograr la inversión.
//Q 是一个队列,S 是一个空栈,实现将队列中的元素逆置的算法。
void Reverse(Queue& Q, Stack& S) {
    
    
	int x;
	while (!IsEmpty(Q)) {
    
    //出队列入栈
		DeQueue(Q, x);
		Push(S, x);
	}
	while (!IsEmpty(S)) {
    
    //出栈入队列
		Pop(S, x);
		EnQueue(Q, x);
	}
}

Supongo que te gusta

Origin blog.csdn.net/knighthood2001/article/details/132526687
Recomendado
Clasificación