Estrutura de dados: pilha sequencial e pilha em cadeia

Pilha

A pilha é uma tabela linear com Last In Fast Out. É limitada a inserir e excluir tabelas lineares no final da tabela.A extremidade que permite a inserção e exclusão é chamada de topo da pilha.

Diagrama de pilha

Insira a descrição da imagem aqui

Variação stack-in e out-of-stack

Os elementos da pilha mais avançada não são necessariamente removidos por último, porque a pilha restringe as posições de inserção e exclusão da tabela linear e não limita o tempo para os elementos entrarem e saírem, ou seja, quando nem todos os elementos são colocados na pilha , O elemento que vai primeiro também pode ser exibido, desde que seja o elemento do topo da pilha.

Por exemplo, os elementos de número inteiro 1, 2 e 3 são colocados na pilha, por sua vez, e a ordem de empilhamento pode ser:

  • O primeiro tipo, 1, 2, 3 dentro, então 3, 2, 1, fora, a ordem de empilhamento 321
  • O segundo tipo, 1 entra, 1 sai, 2 entra, 2 sai, 3 entra, 3 sai, fora da ordem de pilha 123
  • O terceiro tipo, 1 dentro, 2 dentro, 2 fora, 1 fora, 3 dentro, 3 fora, fora da ordem de pilha 213
  • O quarto tipo, 1 entra, 1 sai, 2 entra, 3 entra, 3 sai, 2 sai, fora da ordem da pilha 132
  • O quinto tipo, 1 dentro, 2 dentro, 2 fora, 3 dentro, 3 fora, 1 fora, empilhar sequência 231

Existem 5 ordens de empilhamento para 3 elementos

Estrutura de armazenamento sequencial da pilha

A pilha é um caso especial da tabela linear. A estrutura de armazenamento sequencial da pilha é, na verdade, uma simplificação do armazenamento sequencial da tabela linear, chamada pilha sequencial. A estrutura da pilha sequencial é a seguinte:

typedef int ElemType;   /* ElemType类型根据实际情况而定,这里假设为int */  
typedef struct Stack
{
    
    
	Elemtype *elem;
	int top;   /* 用于栈顶指针 */
	int stacksize;  /* 栈的空间大小 */
}SqStack;

Inicialização da pilha sequencial

  1. Abra o espaço inicial
  2. Inicializar no topo
  3. Initialize stacksize
void InitStack(PStack st)
{
    
    
	assert(st != NULL);  //确保st不为空指针
			
	st->elem = (ElemType*)malloc(sizeof(ElemType)*STACK_INIT_SIZE);
	st->stacksize = STACK_INIT_SIZE;
	st->top = -1;
}

Expansão de pilha sequencial

  1. Abra espaço
  2. Atualizar tamanho da pilha
static void AppendStack(PStack st)//扩容
{
    
    
	assert(st != NULL);
	
	st->elem = (ElemType*)realloc(st->elem, st->stacksize + sizeof(ElemType)*STACKINCREMENT);
	st->stacksize += STACKINCREMENT;
}

Push da pilha sequencial (Push)

Insira a descrição da imagem aqui
Para a operação push, três coisas são realmente feitas

  1. Julgue que a pilha está cheia
  2. Ponteiro superior da pilha mais um
  3. Atribuir o elemento recém-inserido ao espaço superior da pilha
void Push(PStack st, ElemType val)
{
    
    
	assert(st != NULL);
		
	if (st->top == st->stacksize)  //判断栈满
	{
    
    
		AppendStack(st);
	}
	st->top++;  //栈顶指针加一
	st->elem[st->top] = val;  //将新插入元素赋值给栈顶空间
	
}

Pop da pilha sequencial (Pop)

Se a pilha não estiver vazia, coloque o elemento superior da pilha em e e diminua o ponteiro superior em um

int Pop(PStack st, ElemType *e)  // 若栈不为空,则弹出栈顶元素给e,栈顶指针减一
{
    
    
	assert(st != NULL);
		
	if (st->top >= 0)
	{
    
    
		*e = st->elem[st->top];
		st->top--;
		return 1;
	}
	return 0;	
}

Destruição da pilha sequencial

void Destory(PStack st)
{
    
    
	assert(st != NULL);

	free(st->elem);
	st->elem = NULL;
	st->stacksize = 0;
}

Esvaziamento de pilha sequencial

void Clear(PStack st)
{
    
    
	assert(st != NULL);
	
	st->top = 0;
}

A pilha de sequência está vazia

bool IsEmpty(PStack st)
{
    
    
	assert(st != NULL);

	return st->top == -1;
}

Obtenha o elemento superior da pilha sequencial

ElemType GetTop(PStack st)
{
    
    
	assert(st != NULL);
	return st->elem[st->top];
}

Estrutura de armazenamento em cadeia da pilha

A estrutura de armazenamento em cadeia da pilha deve implementar a pilha em um modo de lista vinculada, denominado pilha em cadeia. A
pilha em cadeia coloca o topo da pilha no topo da lista única vinculada, conforme mostrado na figura a seguir: A
Insira a descrição da imagem aqui
estrutura da pilha em cadeia é a seguinte:

typedef struct StackNode  // 栈结点
{
    
    
	ElemType data;
	struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack  // 链栈
{
    
    
	LinkStackPtr top;
	int count;
}LinkStack;

A maioria das operações da pilha em cadeia são semelhantes às de uma lista unida individualmente, exceto para inserções e exclusões.

Empurrar a pilha de corrente (Empurrar)

Supondo que o novo nó s cujo valor do elemento é e deve ser colocado na pilha, e top é o ponteiro do topo da pilha, o diagrama esquemático de empurrar para a pilha é o seguinte:
Insira a descrição da imagem aqui

  1. Atribuir o elemento do topo da pilha atual ao sucessor imediato do novo nó
  2. Atualize o ponteiro superior da pilha para apontar para o novo elemento
Status Push(LinkStack *LS, ElemType e)
{
    
    
	LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StacNode));
	s->data = e;
	
	s->next = LS->top; //将当前的栈顶元素赋值给新节点的直接后继
	LS->top = s;  //更新栈顶指针,使其指向新元素
	
	LS->count++;
	
	return OK;
}

Pop da pilha de corrente (Pop)

Suponha que a variável p seja usada para armazenar o nó superior da pilha a ser excluída

  1. Atribua o nó superior da pilha a p, conforme mostrado na etapa 1
  2. O ponteiro do topo da pilha se move um bit para baixo, conforme mostrado na etapa 2 abaixo
  3. Nó de liberação p

Insira a descrição da imagem aqui

//若栈不为空,则删除栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(LinkStack *S, ElemType *e)
{
    
    
	LinkStackPtr p;
	if(StackEmpty(*S))
	{
    
    
		return ERROR;
	}
	*e = S->top->next;
	
	p = S->top; //将栈顶结点赋值给p,如上图步骤1
	S->top = S->top->next;  //栈顶指针下移一位,如上图步骤2
	free(p);  //释放结点p
	S->count--;
	
	return OK;
}

Comparação de pilha sequencial e pilha de cadeia

A complexidade de tempo de empilhamento e empilhamento de pilha sequencial e pilha em cadeia é O (1). Para desempenho de espaço, a pilha sequencial precisa determinar um comprimento fixo com antecedência, o que pode causar um desperdício de espaço de memória, mas sua vantagem é que é fácil de acessar e localizar, enquanto a pilha em cadeia requer que cada elemento tenha um campo de ponteiro, que também Algum overhead de memória é adicionado, mas o comprimento da pilha pode ser desenvolvido de forma flexível. Portanto, a diferença entre eles é como a diferença entre uma lista sequencial e uma lista vinculada.
Se a mudança de elementos durante o uso da pilha for imprevisível, às vezes pequena, às vezes grande, então é melhor usar uma pilha em cadeia; por outro lado, se suas mudanças estiverem dentro de uma faixa controlável, você pode usar uma pilha sequencial

Acho que você gosta

Origin blog.csdn.net/huifaguangdemao/article/details/108348862
Recomendado
Clasificación