<Estrutura de dados> Implementação da pilha

contente

prefácio

       conceito de pilha

       estrutura da pilha

Implementação de pilha

       Criar estrutura de pilha

       inicializar pilha

       destruir pilha

       empurre para a pilha

       estourar

       Obter o elemento superior da pilha

       Obter o número de elementos válidos na pilha

       Verifique se a pilha está vazia

código total

       Arquivo Stack.h

       Arquivo Stack.c

       Arquivo Test.c


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;
}

Acho que você gosta

Origin blog.csdn.net/bit_zyx/article/details/123763458
Recomendado
Clasificación