1 El concepto básico de la pila
La pila es una mesa especial que solo se inserta y elimina en la cabecera de la mesa. Por lo tanto, la cabecera de la mesa tiene un significado especial para la pila, que se denomina la parte superior de la pila. El final de la mesa se llama la parte inferior de la pila. Una pila que no contiene ningún elemento se llama pila vacía.
Suponiendo que los elementos en una pila S son a (n), a (n-1), ..., a (1), entonces a (1) se llama el elemento inferior de la pila, y a (n) es el elemento superior de la pila. Los elementos de la pila se introducen en la pila en el orden de a (1), a (2), ..., a (n). En cualquier momento, el elemento que se extrae de la pila es el elemento superior de la pila . En otras palabras, la modificación de la pila se lleva a cabo según el principio de último en entrar, primero en salir. Por lo tanto, la pila también se denomina tabla Último en entrar, primero en salir (Último en entrar, primero en salir), o tabla LIFO para abreviar .
La pila también es un tipo de datos abstracto. Las operaciones de pila más utilizadas son las siguientes.
(1) StackEmpty (S): prueba si la pila S está vacía.
(2) StackFull (S): prueba si la pila S está llena.
(3) StackTop (S): Devuelve el elemento superior de la pila S.
(4) Empujar (x, S): Inserte el elemento x en la parte superior de la pila S, lo que se conoce como empujar el elemento x sobre la pila.
(5) Pop (S): elimina y devuelve el elemento superior de la pila S, denominado pila pop.
La aplicación de la pila es muy amplia, siempre que el problema satisfaga el principio LIFO, se puede utilizar la pila.
2 Use una matriz para implementar una pila
Cuando los datos de una matriz se utilizan para almacenar elementos de la pila, la parte inferior de la pila se fija en la parte inferior de la matriz, es decir, los datos [0] son el primer elemento que se coloca en la pila y la pila se expande a la parte superior de la matriz (en la dirección de aumentar el subíndice).
2.1 Estructura de pila implementada con matriz
La pila se define de la siguiente manera.
typedef struct astack *Stack;//栈指针类型
typedef struct astack;//栈结构
int top,//栈顶
maxtop;//栈空间上界
StackItem *data;//存储栈元素的数组
}Sstack;
El elemento de la pila se almacena en los datos de la matriz, con top apuntando a la posición superior de la pila actual, el elemento superior de la pila se almacena en los datos [top] y la capacidad de la pila es maxtop.
2.2 Definición de tipo de elementos de pila
Defina el tipo de elemento de pila como int.
typedef int StackItem;//栈元素类型int
typedef StackItem *addr;//栈元素指针类型
2.3 Función StackInit (tamaño)
Cree una pila vacía con una capacidad de tamaño.
Stack StackInit(int size)
{
Stack S=(Stack)malloc(sizeof *S);
S->data=(StackItem *)malloc(size*sizeof(StackItem));
S->maxtop=size;
S->top=-1;
return S;
}
2.4 Función StackEmpty (S)
Cuando top = -1, la pila actual está vacía.
int StackEmpty(Stack S)
{
return S->top<0;
}
2.5 Función StackFull (S)
Cuando top = maxtop, la pila actual está llena.
int StackFull(Stack S)
{
return S->top>=S->maxtop;
}
2.6 Función StackTop (S)
El elemento superior de la pila se almacena en datos [top].
StackItem StackTop(Stack S)
{
//前提栈为非空
if(StackEmpty(S)) exit(1);
return S->data[S->top];
}
2.7 Función Push (x, S)
El nuevo elemento superior x debe almacenarse en datos [top + 1].
void Push(StackItem x,Stack S)
{
//前提栈未满
if(StackFull(S)) exit(1);
S->data[++S->top]=x;
}
2.8 Función Pop (S)
Después de eliminar el elemento superior de la pila, el nuevo elemento superior de la pila está en data [top-1].
StackItem Pop(Stack S)
{
//栈为非空
if(StackEmpty(S)) exit(1);
return S->data[S->top--];
}
2.9 Función StackFree (S)
Dado que los datos de la matriz se asignan dinámicamente, StackFree debería liberar el espacio asignado a los datos al final del uso para evitar pérdidas de memoria.
void StackFree(Stack S)
{
free(S->data);
free(S);
}
2.10 Usar múltiples pilas
Cuando se utilizan pilas en algunos algoritmos, a menudo es necesario utilizar varias pilas al mismo tiempo. Para evitar que cada pila se desborde durante la ejecución del algoritmo, normalmente se establece un espacio de pila más grande para cada pila. Pero no es fácil hacer esto, porque el espacio máximo realmente utilizado por cada pila en el proceso de operación del algoritmo es difícil de estimar . Por otro lado, el tamaño real de cada pila cambia constantemente durante la operación del algoritmo y, a menudo, sucede que una pila está llena y la otra vacía.
] Suponga que las dos pilas del programa comparten una matriz de datos [0: n]. Usando la función de que la posición inferior de la pila permanece sin cambios, la parte inferior de las dos pilas se puede establecer en los dos extremos de los datos de la matriz y luego cada una se extiende hacia la mitad de los datos de la matriz. Los valores iniciales de las partes superiores de las dos pilas son 0 y n respectivamente, y puede producirse un desbordamiento cuando las partes superiores de las dos pilas se encuentran. Dado que las dos pilas pueden complementarse entre sí, el espacio máximo real disponible para cada pila suele ser mayor que n / 2.
Dos pilas que comparten el mismo espacio de matriz
3 Implementar la pila con punteros
Se utiliza un puntero para implementar una pila, denominada pila en cadena, como se muestra en la figura siguiente.
3.1 La definición del tipo de nodo de la pila de cadenas
typedef struct snode *slink;//栈结点指针类型
typedef struct snode{
//栈结构
StackItem element;//栈元素
slink next;//下一结点指针
}StackNode;
slink NewStackNode()
{
return (slink)malloc(sizeof(StackNode));
}
Su elemento miembro de datos almacena elementos de la pila, el siguiente es un puntero al siguiente nodo y la función NewStackNode () crea un nuevo nodo.
3.2 Chain stack Stack implementado con punteros
typedef struct lstack *Stack;//栈指针类型
typedef struct lstack{
//栈结构
slink top;//栈顶指针
}Lstack;
top es un puntero al nodo superior de la pila.
3.3 Función StackInit (tamaño)
La función StackInit () establece top en un puntero nulo y crea una pila vacía.
Stack StackInit()
{
Stack S=(Stack)malloc(sizeof *S);
S->top=0;
return S;
}
3.4 Función StackEmpty (S)
Compruebe si la parte superior del puntero a la parte superior de la pila es un puntero nulo.
int StackEmpty(Stack S)
{
return S->top==0;
}
3.5 Función StackTop (S)
Devuelve el elemento en el nodo superior de la pila S.
StackItem StackTop(Stack S)
{
//前提栈为非空
if(StackEmpty(S)) exit(1);
return S->top->element;
}
3.6 Función Push (x, S)
La función Push (x, S) primero crea un nuevo nodo para el elemento x, y luego modifica la parte superior del puntero del nodo de la pila de S para convertir el nuevo nodo en el nuevo nodo superior de la pila.
void Push(StackItem x,Stack S)
{
slink p=NewStackNode();
p->element=x;
p->next=S->top;
S->top=p;
}
3.7 Función Pop (S)
La función Pop (S) primero almacena el elemento superior de S en x, luego modifica el puntero de la parte superior de la pila para apuntar al siguiente elemento del elemento superior de la pila, eliminando así el elemento superior de la pila y finalmente devuelve x.
StackItem Pop(Stack S)
{
//前提栈非空
if(StackEmpty(S)) exit(1);
StackItem x=S->top->element;
slink p=S->top;
S->top=p->next;
free(p);
return x;
}