> 技术文档 > 栈的核心原理

栈的核心原理


1 栈的概念及结构

栈是一种特殊的线性表,其特点是只允许在固定的一端进行插入和删除操作。进行操作的一端称为栈顶,另一端称为栈底

栈中的元素遵循后进先出(LIFO,Last In First Out) 原则。

  • 压\\入\\进栈(Push):在栈顶插入元素的操作
  • 出栈(Pop):从栈顶删除元素的操作

 

2 栈的实现

栈可以通过数组或链表实现,数组实现更为高效(尾插尾删的时间复杂度为 O (1))。

 

2.1 栈的结构定义及声明

#pragma once#include#include#include#includetypedef STDataType;//定义typedef struct Stack{STDataType* a;int top;int capacity;}ST;// 初始化void STInit(ST* pst);// 销毁void STDestroy(ST* pst);// 插入数据(入栈)void STPush(ST* pst, STDataType x);//删除数据(出栈)void StackPop(ST* pst);// 获取栈顶元素STDataType STTop(ST* pst);// 栈的判空bool STEmpty(ST* pst);// 栈的大小(获取栈中数据个数)int STSize(ST* pst);

2.2 核心操作实现

1.初始化

// 初始化void STInit(ST* ps){ assert(ps); ps->a = NULL; ps->top = 0; // 设定初始栈顶为0,表示无元素 ps->capacity = 0;}

2.销毁

// 销毁void STDestroy(ST* ps){ assert(ps); free(ps->a); ps->a = NULL; ps->top = ps->capacity = 0;}

3.入栈操作

原本栈为空时,top 为-1,为了便于写代码,令为 0

 原本 top 指向栈顶元素的,没有元素时候,指向 -1,不指向 0。

所以对于上述两种情况,

情况一:

top 指向栈顶数据。

情况二:

top 指向栈顶数据的下一个位置。

// 插入数据(入栈)void STPush(ST* ps, STDataType x){ assert(ps); // 检查容量,不足则扩容 if (ps->top == ps->capacity) //相等就扩容 { int newCapacity = ps->capacity == 0 ? 4 : ps->capacity* 2; //最初时候都是0,刚开始开空间开4个 STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType)); if (tmp == NULL) { perror(\"realloc fail\"); return; } ps->a = tmp; ps->capacity = newCapacity; } // 存入数据后栈顶上移 ps->a[ps->top] = x; ps->top++;}

4.出栈操作

void StackPop(ST* ps){ assert(ps); // 栈顶下移即完成出栈 ps->top--;  }

5.获取栈顶元素

// 获取栈顶元素STDataType STTop(ST* ps){ assert(ps); //assert(!STEmpty(ps)); assert(ps->top > 0); //避免空栈 return ps->a[ps->top - 1];}

6.栈的判空

// 栈的判空bool STEmpty(ST* ps){ assert(ps); return ps->top == 0;}

 7.栈的大小

// 栈的大小(获取栈中数据个数)int STSize(ST* ps){ assert(ps); return ps->top;}

2.3 测试一下

#define _CRT_SECURE_NO_WARNINGS 1#include\"Stack.h\"int main(){ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);//访问元素while (!STEmpty(&s)){printf(\"%d \", STTop(&s));STPop(&s);}STDestroy(&s);return 0;}