contente
Obter o elemento superior da pilha
Obter o número de elementos válidos na pilha
Verifique se a pilha está vazia
prefácio
conceito de pilha
- Pilha: Uma lista linear especial que permite a inserção e remoção de elementos apenas em uma extremidade fixa. Uma extremidade onde a inserção e a exclusão de dados são realizadas é chamada de topo da pilha e a outra extremidade é chamada de fundo da pilha. Os elementos de dados na pilha seguem o princípio LIFO (Last In First Out). Como um pente de pistola, a última bala carregada sempre é disparada primeiro, a menos que a arma esteja quebrada.
- Push stack: A operação de inserção da pilha é chamada push/push/push. (Os dados de entrada estão no topo da pilha)
- Pop: A exclusão da pilha é chamada de pop. (Os dados de saída também estão no topo da pilha)
Perceber:
1. As chamadas de função também possuem pilhas.Existe alguma diferença entre essas duas pilhas?
Claro que existem diferenças. A chamada da função chamará o quadro de pilha, e também há uma pilha na memória. Quando o programa é executado, a função precisa ser executada. As variáveis locais, parâmetros, valores de retorno, etc. na função devem ser armazenados no quadro de pilha de funções.
As duas pilhas não têm nada a ver uma com a outra, uma é a pilha na estrutura de dados. A outra é uma área de memória dividida no sistema operacional, chamada de pilha, que é usada para criar um quadro de pilha quando uma função é chamada. Embora não haja conexão na natureza, todos eles obedecem à regra do último a entrar, primeiro a sair.
2. Suponha que a sequência de empilhamento seja: 1 2 3 4, então a sequência pop-out deve ser: 4 3 2 1?
claro que não. Embora as regras sejam claramente LIFO, isso é relativamente falando. Se for dito que cada vez que ele entra em um e depois um é liberado, e então continua a empurrar a pilha, isso também não está de acordo com o último em primeiro- fora regra? Assim como no exemplo acima, não é de surpreender que você diga que a ordem de empilhamento é 1 2 3 4. Cada vez que você insere um, um sai e outro entra, o que também está de acordo com as regras. Também é possível colocar dois na pilha e depois entrar e sair novamente, como 2 1 4 3.
estrutura da pilha
Implementação de pilha
Criar estrutura de pilha
- Arquivo Stack.h:
//创建栈结构 typedef int STDataType; typedef struct Stack { STDataType* a; //存储数据 int top; //栈顶的位置 int capacity; //容量 }ST;
inicializar pilha
- Pensamento:
A inicialização é relativamente simples. Depois de aprender a tabela de sequência anterior, é muito fácil inicializar a pilha
- Arquivo Stack.h:
//初始化栈 void StackInit(ST* ps);
- Arquivo Stack.c:
//初始化栈 void StackInit(ST* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; }
- Perceber:
É intencional definir top como 0 ao inicializar aqui. Em primeiro lugar, foi marcado quando a estrutura da pilha foi criada acima. top é usado para registrar a posição do topo da pilha. Como é a posição do topo da pilha, quando top é inicializado com 0, nós pode colocar os dados diretamente na pilha e, em seguida, top++ , mas quando top é inicializado como -1, top precisa de ++ para colocar os dados primeiro, porque os dados não podem ser colocados em uma posição em que um número negativo não pertença à pilha. A figura a seguir demonstra o processo:
Este artigo usa top = 0 como exemplo
destruir pilha
- Pensamento:
O espaço de memória aberto dinamicamente deve ser liberado, livre pode ser definido como vazio e o restante dos dados é definido como 0.
- Arquivo Stack.h:
//销毁栈 void StackDestory(ST* ps);
- Arquivo Stack.c:
//销毁栈 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; }
empurre para a pilha
- Ideias:
O artigo anterior enfatizou que top é inicializado com 0, portanto deve ser colocado diretamente nos dados, e top++, mas antes disso, é necessário avaliar se o espaço é suficiente. Quando top=capacity, a pilha está cheia, então realloc precisa ser expandido.
- Arquivo Stack.h:
//压栈 void StackPush(ST* ps, STDataType x);
- Arquivo Stack.c:
//压栈 void StackPush(ST* ps, STDataType x) { assert(ps); //如果栈满了,考虑扩容 if (ps->top == ps->capacity) { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量 ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType)); if (ps->a == NULL) { printf("realloc fail\n"); exit(-1); } ps->capacity = newcapacity; //更新容量 } ps->a[ps->top] = x;//将数据压进去 ps->top++;//栈顶上移 }
estourar
- Ideias:
Antes de abrir a pilha, certifique-se de que o topo não esteja vazio e que a condição para que o topo não esteja vazio seja top>0, então você também deve afirmar que top>0 e, em seguida, mover diretamente o topo da pilha para baixo -- é isso. Semelhante à ideia de uma tabela de sequências.
- Arquivo Stack.h:
//出栈 void StackPop(ST* ps);
- Arquivo Stack.c:
//出栈 void StackPop(ST* ps) { assert(ps); assert(ps->top > 0); ps->top--; }
Obter o elemento superior da pilha
- Ideias:
Em primeiro lugar, devemos descobrir quem é o elemento superior da pilha, é a posição superior ou a posição superior 1? Obviamente, a posição top-1 é o elemento de topo da pilha, porque foi claramente apontado que top era 0 durante a inicialização acima, e os dados foram colocados diretamente na pilha quando foram empurrados. subscrito de dados é 0, e então + +top e, em seguida, empurrar outros dados, pode-se ver que o elemento superior da pilha é a posição do subscrito top-1.
- Arquivo Stack.h:
//访问栈顶数据 STDataType StackTop(ST* ps);
- Arquivo Stack.c:
//访问栈顶数据 STDataType StackTop(ST* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素 }
Obter o número de elementos válidos na pilha
- Pensamento:
Como mencionado acima, o subscrito top-1 é o elemento superior da pilha, então isso significa que existem elementos top-1 no total? Claro que não, aqui está a mesma ideia do subscrito do array, o número de elementos deve estar no topo, basta retornar diretamente.
- Arquivo Stack.h:
//有效元素个数 int StackSize(ST* ps);
- Arquivo Stack.c:
//有效元素个数 int StackSize(ST* ps) { assert(ps); return ps->top; }
Verifique se a pilha está vazia
- Ideias:
Quando o valor de top é 0, ele está vazio e return pode ser retornado diretamente.
- Arquivo Stack.h:
//判空 bool StackEmpty(ST* ps);
- Arquivo Stack.c:
//判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; //如果top为0,那么就为真,即返回 }
- Arquivo teste.c:
void TestStack() { ST st; StackInit(&st); StackPush(&st, 1); StackPush(&st, 2); StackPush(&st, 3); StackPush(&st, 4); while (!StackEmpty(&st)) { printf("%d ", StackTop(&st)); StackPop(&st); } printf("\n"); StackDestory(&st); }
- O efeito é o seguinte:
código total
Arquivo Stack.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> //创建栈结构 typedef int STDataType; typedef struct Stack { STDataType* a; //存储数据 int top; //栈顶的位置 int capacity; //容量 }ST; //初始化栈 void StackInit(ST* ps); //销毁栈 void StackDestory(ST* ps); //压栈 void StackPush(ST* ps, STDataType x); //出栈 void StackPop(ST* ps); //判空 bool StackEmpty(ST* ps); //访问栈顶数据 STDataType StackTop(ST* ps); //有效元素个数 int StackSize(ST* ps);
Arquivo Stack.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"Stack.h" //初始化栈 void StackInit(ST* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; } //销毁栈 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; } //压栈 void StackPush(ST* ps, STDataType x) { assert(ps); //如果栈满了,考虑扩容 if (ps->top == ps->capacity) { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量 ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType)); if (ps->a == NULL) { printf("realloc fail\n"); exit(-1); } ps->capacity = newcapacity; //更新容量 } ps->a[ps->top] = x;//将数据压进去 ps->top++;//栈顶上移 } //出栈 void StackPop(ST* ps) { assert(ps); assert(ps->top > 0); ps->top--; } //判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; //如果top为0,那么就为真,即返回 } //访问栈顶数据 STDataType StackTop(ST* ps) { assert(ps); return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素 } //有效元素个数 int StackSize(ST* ps) { assert(ps); return ps->top; }
Arquivo Test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"Stack.h" void TestStack() { ST st; StackInit(&st); StackPush(&st, 1); StackPush(&st, 2); StackPush(&st, 3); StackPush(&st, 4); while (!StackEmpty(&st)) { printf("%d ", StackTop(&st)); StackPop(&st); } printf("\n"); StackDestory(&st); } int main() { TestStack(); return 0; }