El funcionamiento básico de la pila (chain stack) de la estructura de datos

1. En cuanto a la operación de la pila enlazada, es muy similar a la lista enlazada, la diferencia es que la pila solo permite la operación de empuje en la parte superior de la pila, que es lo mismo que el método de inserción de encabezado de la lista enlazada. .

2. La razón para usar la pila en cadena es que si usamos la pila secuencial, necesitamos solicitar un espacio de memoria por adelantado, pero si almacenamos una pequeña cantidad de elementos, este espacio de memoria inevitablemente causará cierto desperdicio. Si se usa la pila de cadena, solo solicitamos memoria cuando se inserta en la pila y luego almacenamos los elementos, que pueden realizar la aplicación de memoria dinámica. Puede solicitar el espacio requerido de acuerdo con el número real de elementos en la pila.

3. Las operaciones básicas de la pila en cadena y la pila secuencial son las mismas, incluyendo: inicialización, encontrar la longitud, juzgar si la pila está vacía, empujar la pila, abrir la pila y tomar el elemento superior de la pila.

(1) Primero defina una estructura, que incluya los datos de valor de nodo de cada nodo en la pila, y el puntero al lado del siguiente nodo de pila

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
//定义一个结构体栈
typedef struct StackNode
{
    ElemType data;
    struct StackNode *next;
}StackList;
typedef StackList *LStack;//声明一个指向这个结构体的指针类型Lstack

(2) Inicialice, configure un puntero en la parte superior de la pila de la cadena para que apunte a la pila. Este puntero no almacena nada, así que simplemente configure el puntero superior de la pila en NULL al principio.

//初始化链栈
void Init(LStack *s)
{
    (*s)=(LStack)malloc(sizeof(StackList));
    (*s)->next=NULL;
}

(3) Para juzgar si la pila está vacía, solo es necesario juzgar si el campo de puntero del puntero superior de la pila está vacío. Devuelve 0 para nulo, 1 para no nulo.

//判断栈是否为空
int Empty(LStack s)
{
    if(s->next==NULL)
    {
        return 0;//为空返回0,
    }
    return 1;    //不为空返回1,
}

(4) Encuentre la longitud de la pila, es decir, comience desde el siguiente elemento en la parte superior de la pila, es decir, el primer elemento, recorra hacia abajo y recorra hasta que el puntero apunte a nulo, lo que indica que el recorrido está completo , si no se recorre uno, el contador se incrementa en uno, temporal La variable puntero se mueve un bit hacia atrás p=p->siguiente

//求栈中的元素数量,即长度
int Printf(LStack s)
{
    int count=0;
    LStack p;
    p=s->next;//指向第一个元素
    while(p){
        count++;
        p=p->next;
    }
    return count;
}

(5) Empuje la pila, empuje el valor x en la pila, primero declaramos una variable de puntero para almacenar el valor del elemento x, por supuesto, porque queremos usar esta variable de puntero para almacenar cosas, por lo que primero debemos para este puntero variable Solicite espacio de memoria malloc y luego guárdelo.

//入栈
void Push(LStack *s,ElemType x)
{
    LStack p;//声明一个指针变量
    p=(LStack)malloc(sizeof(StackList));//为这个指针变量分配空间
    p->data=x;        //将入站的元素值存入到这个指针的数据域
    p->next=(*s)->next;  //这两个步骤和顺序链表的操作相似。
    (*s)->next=p;
}

(6) Para salir de la pila, primero debemos determinar si la pila está vacía. Si no lo está, nuestro puntero p apunta al primer nodo de la pila, y luego usamos e para registrar el valor de la pila actual. elemento superior de la pila, y luego almacenaremos la pila sin nada.El campo de puntero del puntero superior apunta al siguiente nodo del puntero p, y el puntero p se puede liberar.

//出栈
ElemType Pop(LStack *s)
{
    LStack p;//声明一个结构体类型的指针变量
    ElemType e;
    p=(*s)->next;//指向栈中的栈顶元素
    if(p==NULL)
    {
        return 0;
    }
    (*s)->next=p->next;//不为空的话就让栈顶元素变成当前栈顶p的下一个
    e=p->data;//存放以下删除的栈顶元素
    free(p);  //释放指针
    return e; //返回删除的栈顶指针的值
}

(7) Para obtener el valor del elemento en la parte superior de la pila, primero determine si la pila está vacía. Si no lo está, simplemente devuelva el valor del primer nodo de la pila.

//取栈顶元素的值
ElemType GetTop(LStack s)
{
    if(Empty(s)){//如果栈顶元素不为空的话,则打印出栈顶元素
        return s->next->data;
    }
    return 0;
}

(8) La función principal, defina cada función definida anteriormente, el bloque de código de este módulo, puede definirlo usted mismo según sus propias necesidades, solo doy una parte de lo que escribí

int main()
{
    LStack s;
    int x;
    ElemType e;
    //初始化栈
    Init(&s);
    //判断栈是否为空
    x=Empty(s);
    if(x)
    {
        printf("栈空\n");
    }
    //扫描要入站的元素
    Push(&s,5);
    Push(&s,4);
    Push(&s,6);
    Push(&s,8);
    Push(&s,2);
    //获取栈的长度
    x=Printf(s);
    printf("栈的长度为%d\n",x);
    //获取当前栈的栈顶元素
    e=GetTop(s);
    if(e){//如果栈不为空的话输出
        printf("当前栈顶元素为:%d\n",e);
    }
    //删除当前栈的栈顶元素
    e=Pop(&s);
    if(x)//如果栈不为空的话进行出栈操作
    {
        printf("删除的元素为:%d\n",e);
    }
    //获取当前的栈顶元素
    e=GetTop(s);
    if(e){//如果栈不为空的话输出
        printf("当前栈顶元素为:%d\n",e);
    }
    x=Printf(s);
    printf("栈的长度为%d\n",x);
    return 0;
}

(9) El resultado final de mi caso es:

Resumen: algunas personas no saben cómo escribir cuando definen un puntero a una estructura cuando lo pasan a otra función. Si define el tipo de estructura que no es un puntero, entonces Si define una variable de puntero de estructura en la principal función, necesita usar un puntero doble** para cambiar la pila al pasarla a otras funciones. Definí un tipo de puntero a la estructura al principio aquí, luego I Al declarar un puntero a un tipo de estructura, no necesita agregar *, el principio es el mismo. Si hay algún error, deje un mensaje, si hay una mejor manera, bienvenido a comunicarse.

 

Supongo que te gusta

Origin blog.csdn.net/BaoITcore/article/details/121257979
Recomendado
Clasificación