Página inicial pessoal: Página inicial pessoal
Coluna pessoal: "Estrutura de dados" "Linguagem C"
Diretório de artigos
prefácio
Pilha: Uma estrutura linear especial que permite apenas a inserção e exclusão de dados em uma extremidade. A extremidade que permite a manipulação dos dados é chamada de topo da pilha e a outra extremidade é chamada de parte inferior da pilha .
O que este blog irá implementar é uma pilha de array .
1. A ideia de implementação da pilha
Para a particularidade da pilha, a complexidade de tempo de implementação de uma pilha com uma matriz (inserir e excluir dados no final da matriz) e uma lista vinculada (conectar e excluir dados no topo) é O(1), que é não é difícil. Vantagens e desvantagens
da pilha de array
- Arrays suportam acesso aleatório (acessam dados com subscritos), e muitos algoritmos requerem suporte de acesso aleatório, como dicotomia...
- Alta utilização de cache
inferior
- Quando o espaço não for suficiente, amplie a capacidade
- às vezes desperdiça espaço
1. Definição de estrutura
A estrutura da pilha é muito simples
: um ponteiro para o espaço aberto dinamicamente, uma variável para registrar o tamanho real do espaço e um subscrito para registrar o elemento superior da pilha.
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int top;//栈顶下标
int capacity;//空间大小
}Stack;
2. Inicialize a pilha (StackInit)
O ponteiro de dados aponta para o espaço aberto dinamicamente, a capacidade registra o tamanho do espaço neste momento e top é definido como 0.
- top é definido como 0, indicando a posição onde os dados do topo da pilha serão inseridos.
- top é definido como -1, indicando a posição dos dados superiores na pilha neste momento.
Aqui, top está definido como 0.
//初始化栈
#define SIZE 4
void StackInit(Stack* ps)
{
assert(ps);
ps->data = (STDataType*)malloc(sizeof(STDataType) * SIZE);
if (ps->data == NULL)
{
perror("malloc");
exit(-1);
}
ps->top = 0;
ps->capacity = SIZE;
}
3. Empurre para a pilha (StackPush)
Como top é inicializado com 0, você pode inserir dados diretamente no subscrito de top. Mas preste atenção, verifique a capacidade antes de inserir os dados, se top == capacidade, é necessário ampliar a capacidade.
- A operação de verificação de capacidade aqui pode ser encapsulada em uma função, mas não é necessária, porque a operação da pilha só precisa verificar a capacidade ao empurrar a pilha, e outras operações não precisam verificar a capacidade. em uma função reduzirá a eficiência (a chamada de função precisa formar um quadro de pilha de funções).
//入栈
void StackPush(Stack* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * (ps->capacity * 2));
if (tmp == NULL)
{
perror("realloc");
exit(-1);
}
ps->data = tmp;
ps->capacity *= 2;
}
ps->data[ps->top] = x;
ps->top++;
}
4. Pop (StackPop)
top indica a posição onde os dados no topo da pilha serão colocados na pilha, portanto, para estourar a pilha, você só precisa subtrair 1 do topo. (Os dados colocados na pilha serão substituídos diretamente na próxima vez)
Mas deve-se notar que quando top = 0, significa que não há dados na pilha e a operação da pilha não pode ser executada.
- A operação pop não pode obter dados
//出栈
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->top != 0);
ps->top--;
}
5. Obtenha o elemento superior da pilha (StackTop)
top aponta para o local onde os dados serão colocados na pilha, ou seja, o próximo local dos dados no topo da pilha.
Então, para colocar os dados no topo da pilha, você só precisa ler top - 1. Mas deve-se notar que se top = 0, então top - 1 = -1 será acessado fora dos limites, portanto, quando top = 0, o elemento superior da pilha não pode ser obtido.
//获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->data[ps->top - 1];
}
6. Verifique se a pilha está vazia (StackEmpty)
top aponta para o local onde os dados serão colocados na pilha e seu valor também indica o número de dados na pilha.
Portanto, só precisamos avaliar top == 0 para saber se a pilha está vazia.
//检查栈是否为空
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;
}
7. Destrua a pilha (StackDestroy)
Libere o espaço aberto dinamicamente, defina a capacidade como 0 e top como 0.
//销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->data);
ps->top = 0;
ps->capacity = 0;
}
2. Implementação de código
O arquivo Stack.h armazena a declaração da função, a referência do arquivo de cabeçalho e a definição da estrutura.
O arquivo Stack.c armazena a implementação da função.
//Stack.h 文件
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#define SIZE 4
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int top;
int capacity;
}Stack;
//初始化栈
void StackInit(Stack* ps);
//入栈
void StackPush(Stack* ps, STDataType x);
//出栈
void StackPop(Stack* ps);
//获取栈顶元素
STDataType StackTop(Stack* ps);
//检查栈是否为空
bool StackEmpty(Stack* ps);
//销毁栈
void StackDestroy(Stack* ps);
//Stack.c 文件
#include "Stack.h"
//初始化栈
void StackInit(Stack* ps)
{
assert(ps);
ps->data = (STDataType*)malloc(sizeof(STDataType) * SIZE);
if (ps->data == NULL)
{
perror("malloc");
exit(-1);
}
ps->top = 0;
ps->capacity = SIZE;
}
//入栈
void StackPush(Stack* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * (ps->capacity * 2));
if (tmp == NULL)
{
perror("realloc");
exit(-1);
}
ps->data = tmp;
ps->capacity *= 2;
}
ps->data[ps->top] = x;
ps->top++;
}
//出栈
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->top != 0);
ps->top--;
}
//获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->data[ps->top - 1];
}
//检查栈是否为空
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;
}
//销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->data);
ps->top = 0;
ps->capacity = 0;
}
Resumir
O texto acima é minha implementação da pilha.