当前位置: 首页 > news >正文

S8 链式栈

3.3链式栈

3.3.1链式栈的核心特性

首先通过表格对比链式栈与顺序栈的差异:

特性对比

顺序栈

链式栈

存储结构

数组(连续内存)

链表(离散内存)

内存分配

静态/动态数组

动态节点分配

扩容方式

需要重新分配内存

按需分配节点,无需扩容

空间效率

可能有空间浪费

每个节点有指针开销

访问效率

O(1)随机访问

O(n)顺序访问

溢出风险

栈满时溢出

几乎不会溢出(除非内存耗尽)

3.3.2链式栈的结构

链式栈的结构定义

typedef struct stacknode {int val; // 数据域struct stacknode* next; // 指针域} stacknode;typedef struct stacklist {stacknode* top; // 栈顶指针int count; // 元素个数} stacklist;

关键特性

  • 动态节点:每个节点独立分配内存,通过指针连接
  • 栈顶指针: top 指向链表的第一个节点(栈顶元素)
  • 不带头节点:第一个节点就是存储实际数据的节点
  • 计数记录: count 记录元素个数,避免遍历计数

函数详细讲解

1. 初始化函数 ( initstack )

void initstack(stacklist* p) {assert(p != NULL);p->count = 0;p->top = NULL;}

代码解读

  • 初始化空栈: top = NULL 表示栈顶为空
  •  count = 0 表示元素个数为零
  • 这是不带头节点的链式栈,结构简洁

2. 节点管理函数

创建节点 ( buynode )

stacknode* buynode() {stacknode* p = (stacknode*)malloc(sizeof(stacknode));if (p == NULL) return NULL;return p;}

释放节点 ( freenode )

void freenode(stacknode* p) {assert(p != NULL);free(p);p = NULL; // 注意:这里只是修改局部变量,不影响外部指针}

关键点

  • 释放单个节点的内存
  •  p = NULL 只在函数内有效,调用方需要自行置空指针

3. 核心栈操作

入栈操作 ( push )

bool push(stacklist* p, int val) {assert(p != NULL);stacknode* newnode = buynode();if (newnode == NULL) return false;newnode->val = val;newnode->next = p->top; // 新节点指向原栈顶p->top = newnode; // 更新栈顶指针p->count++;return true;}

图解入栈过程

入栈前: top → A → B → NULL入栈C: top → C → A → B → NULL步骤:1. C->next = top (即A)2. top = C

关键点

  • 时间复杂度O(1):效率很高
  • 头插法:新节点总是插入在链表头部
  • 动态扩容:无需担心栈满,除非内存耗尽

出栈操作 ( pop )

bool pop(stacklist* p, int* pval) {assert(p != NULL);if(is_Empty(p)) return false;*pval = p->top->val; // 保存栈顶值stacknode* temp = p->top; // 保存要删除的节点p->top = p->top->next; // 栈顶指针下移freenode(temp); // 释放原栈顶节点p->count--;return true;}

图解出栈过程

出栈前: top → C → A → B → NULL出栈C: top → A → B → NULL步骤:1. 保存C的值2. top = C->next (即A)3. free(C)

关键点

  • 时间复杂度O(1):效率很高
  • 需要保存返回值:通过参数返回被删除的栈顶值
  • 内存管理:及时释放节点内存,避免泄漏

4. 辅助操作函数

获取栈顶元素 ( gettop )

bool gettop(stacklist* p, int* pval) {if (is_Empty(p)) return false;*pval = p->top->val; // 获取栈顶值但不删除return true;}

关键点

  • 只读操作:不修改栈的状态
  • 时间复杂度O(1):直接访问栈顶节点
  • 与pop的区别:不删除节点,只是查看栈顶值

判空函数 ( is_Empty )

bool is_Empty(stacklist* p) {if (p->count == 0) return true;return false;// 或者判断:return p->top == NULL;}

获取栈大小 ( StackLength )

int StackLength(stacklist* p) {assert(p != NULL);return p->count; // 直接返回计数,O(1)时间复杂度}

优势:由于维护了 count 计数器,获取大小的时间复杂度是O(1),比遍历链表计数(O(n))高效得多。

5. 遍历与销毁函数

遍历打印 ( PrintInto )

void PrintInto(const stacklist* p) {assert(p != NULL);stacknode* current = p->top;while (current != NULL) {printf("%d ", current->val);current = current->next;}}

代码解读

  • 从栈顶到栈底顺序打印(与入栈顺序相反)
  • 时间复杂度O(n):需要访问每个节点
  • 不修改栈结构:只是读取数据

清空栈 ( ClearElem )

void ClearElem(stacklist* p) {assert(p != NULL);while (p->top != NULL) {stacknode* temp = p->top;p->top = p->top->next;freenode(temp);}p->count = 0;}

销毁栈 ( DestroySeqList )

void DestroySeqList(stacklist* p) {assert(p != NULL);while (p->top != NULL) {stacknode* temp = p->top;p->top = p->top->next;freenode(temp);}p->count = 0;}

关键点

  • 释放所有节点:避免内存泄漏
  • 重置计数器: count = 0 
  • 栈顶指针:执行后 top 为 NULL ,回到初始状态

3.3.3链式栈的优势总结

核心优势

  1. 真正的动态性
  1. 内存完全动态分配,无需预估最大容量
  1. 几乎不会出现栈满情况(除非系统内存耗尽)
  1. 高效的核心操作
  1. 入栈和出栈操作的时间复杂度都是O(1)
  1. 只需要修改指针,不需要移动数据
  1. 内存使用灵活
  1. 每个节点独立分配,内存利用率高
  1. 适合内存碎片化严重的环境

时间复杂度总结

操作

时间复杂度

说明

初始化

O(1)

设置指针和计数器

入栈

O(1)

修改指针连接

出栈

O(1)

修改指针连接

获取栈顶

O(1)

直接访问栈顶节点

判空/大小

O(1)

使用计数器

遍历

O(n)

需要访问每个节点

清空/销毁

O(n)

需要释放每个节点

适用场景推荐

  • 栈大小不可预知或变化很大的场景
  • 内存受限环境:避免一次性分配大块内存
  • 需要频繁动态调整栈容量的应用程序
  • 实现递归函数的调用栈(系统自动管理)
  • 算法实现:如深度优先搜索、表达式求值等
http://www.dtcms.com/a/521745.html

相关文章:

  • 中国免费建站网河间网站建
  • Datawhale25年10月组队学习:math for AI+Task4解析几何
  • 不干净的网站做性南京做网站企业
  • 龙虎榜——20251023
  • 矽塔 SA8206A 输入耐压36V 过流保护阈值1.4A 过压/过流保护芯片 SOT-23
  • seo如何提高网站排名做网站框架
  • 文章博客媒体网站模板怎样给自己的网站做防红连接
  • Flow Matching 时序任务:分布生成与多步动作序列的关联解析
  • 石家庄电商网站排名佛山市网站建设企业
  • 电子商务网站建设重点难点wordpress群组插件
  • 网站建设费税率网页传奇手游官网
  • 模板网站的缺陷wordpress建站的案例
  • 数据结构初阶:Java泛型
  • 推荐个好看的网站自己做网站花钱么
  • 潍坊设计网站wordpress任务论坛
  • 计网第二章——物理层
  • 河北网站推广网站购物车建设
  • 企业营销策略有哪几种莱芜网站优化招聘网
  • 39某健康网旋转验证码---Js逆向分析
  • 网站如何推广开发公司名称起名大全
  • 适合30岁短期培训班泉州seo排名
  • 欧洲稀土产业链
  • wordpress 去除tag自己的网站怎么优化
  • 网站建设多少钱合适临漳手机网站建设
  • 网络编程--TCP通信程序
  • GPIO口输入
  • 学校网站怎么做推广方案网站建设作业百度云资源
  • 随州做网站公司情感营销案例
  • 科技网站新版网站上线怎么看网站使用什么做的
  • 网站制作英文版网站创建公司策划书