首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >数据结构入门:一文搞懂栈的顺序结构

数据结构入门:一文搞懂栈的顺序结构

作者头像
fashion
发布2025-12-31 17:57:27
发布2025-12-31 17:57:27
1710
举报

在数据结构的世界里,“栈” 是一个既基础又实用的概念。它就像我们日常生活中叠放的盘子 —— 只能从最上面拿取,也只能往最上面添加,这种 “后进先出”(LIFO,Last In First Out)的特性,让栈在程序开发中有着广泛的应用。今天我们就来重点聊聊栈的一种实现方式 ——顺序结构,用简单易懂的语言和实际代码案例,带你轻松掌握它的核心知识。

一、什么是栈的顺序结构?

栈的顺序结构,本质上是用数组来实现的栈结构。我们知道数组是一块连续的内存空间,通过下标可以快速访问元素,利用这一特性,顺序栈能高效地完成 “入栈” 和 “出栈” 操作。

你可以把顺序栈想象成一个有固定容量的 “抽屉”:

  • 抽屉的每一层对应数组的一个下标位置;
  • 抽屉最里面(数组起始位置)是栈的底部,最外面(数组末尾方向)是栈的顶部;
  • 我们用一个 “栈顶指针”(通常用变量 top 表示)来标记当前栈顶的位置,通过移动这个指针,就能实现元素的添加和删除。

二、顺序栈的核心操作(附代码解析)

结合开头给出的 C 语言代码案例,我们来逐一拆解顺序栈的核心操作。这些操作是顺序栈的灵魂,掌握它们就等于掌握了顺序栈的使用方法。

1. 栈的定义:用结构体封装数组和栈顶指针

要实现顺序栈,首先得定义它的结构。在 C 语言中,我们通常用结构体来封装两个关键部分:存储元素的数组,以及标记栈顶位置的指针。

#define maxsize 100 // 定义栈的最大容量

typedef int elemtype; // 定义栈中元素的类型(这里是int)

// 栈的结构体定义

typedef struct {

elemtype data[maxsize]; // 存储元素的数组

int top; // 栈顶指针,标记当前栈顶下标

} stack;

这里的data[maxsize]就是我们的 “抽屉”,maxsize规定了抽屉的最大层数(最多能放 100 个元素);top是栈顶指针,它的取值直接反映了栈的状态:

  • 当top = -1时,表示栈是空的(抽屉里没有任何元素);
  • 当top = maxsize - 1时,表示栈已经满了(抽屉被放满了)。
2. 初始化:给栈 “清空” 状态

使用栈之前,必须先进行初始化,也就是把栈顶指针设置为-1,表示这是一个空栈。

void initstack(stack* s) {

s->top = -1; // 栈顶指针置为-1,栈为空

}

这一步就像刚买的抽屉,打开时里面是空的,我们需要先确认它的 “初始状态”,避免后续操作出错。

3. 入栈:往栈顶添加元素(压栈)

入栈就是把新元素放到栈顶的操作,核心是 “移动栈顶指针→存入元素”。

elemtype pushstack(stack* s, elemtype e) {

if (s->top >= maxsize - 1) { // 先判断栈是否已满

printf("栈已满");

return 0; // 入栈失败

}

s->top++; // 栈顶指针上移(指向新的空位置)

s->data[s->top] = e; // 把元素存入新的栈顶位置

return 1; // 入栈成功

}

举个例子:如果当前栈是空的(top = -1),我们要把元素8入栈:

  • 先判断栈未满,然后top从-1变成0;
  • 把8存入data[0],此时栈顶就是8。

再入栈88时,top变成1,88存入data[1],栈顶更新为88—— 这就是 “后进” 的过程。

4. 出栈:从栈顶删除元素

出栈是把栈顶元素取出并删除的操作,核心是 “取出元素→移动栈顶指针”,必须先判断栈是否为空(不能从空抽屉里拿东西)。

elemtype popstack(stack* s, elemtype* e) {

if (s->top == -1) { // 判断栈是否为空

printf("是空的");

return 0; // 出栈失败

}

*e = s->data[s->top]; // 把栈顶元素存入e,供外部使用

s->top--; // 栈顶指针下移,相当于删除栈顶元素

return 1; // 出栈成功

}

还是刚才的例子,栈里有8、88、888三个元素(top = 2):

  • 出栈时先取出data[2]的888,然后top从2变成1;
  • 此时栈顶变成88,下次出栈就会取出88—— 这就是 “先出” 的过程,完美体现 “后进先出”。
5. 查看栈顶元素:只看不取

有时候我们只想知道栈顶是什么元素,不想删除它,这时候就需要 “获取栈顶元素” 的操作,和出栈类似,但不移动栈顶指针。

elemtype gettop(stack* s, elemtype* e) {

if (s->top == -1) { // 判断栈是否为空

printf("是空的");

return 0;

}

*e = s->data[s->top]; // 取出栈顶元素,但不改变top的值

return 1;

}

比如上面出栈888后,用这个函数就能获取到当前栈顶88,而栈的结构不会发生变化。

6. 判断栈空:检查抽屉是否为空

为了避免操作空栈,我们需要一个函数来判断栈是否为空,本质就是检查top是否等于-1。

elemtype is_empty(stack* s) {

if (s->top == -1) {

printf("是空栈\n");

return 1; // 是空栈

} else {

return 0; // 不是空栈

}

}

三、顺序栈的实际运行案例

我们把上面的操作串联起来,看看完整的运行过程(对应代码中的 main 函数):

int main() {

stack s; // 定义一个栈

initstack(&s); // 初始化栈(top = -1)

pushstack(&s,8); // 入栈8 → top=0,data[0]=8

pushstack(&s,88); // 入栈88 → top=1,data[1]=88

pushstack(&s,888);// 入栈888 → top=2,data[2]=888

elemtype e;

popstack(&s,&e); // 出栈 → 取出888,top=1

printf("%d\n",e); // 输出:888

gettop(&s,&e); // 获取栈顶 → 取出88,top仍为1

printf("%d\n",e); // 输出:88

}

运行结果就是先后输出888和88,完全符合 “后进先出” 的规则 —— 最后入栈的888最先出栈,剩下的栈顶就是88。

四、顺序栈的优缺点与应用场景

1. 优点
  • 操作高效:入栈和出栈只需要移动栈顶指针,时间复杂度都是 O (1),速度非常快;
  • 实现简单:基于数组实现,逻辑清晰,代码容易编写和理解;
  • 访问方便:借助数组下标,理论上可以快速访问栈内任意元素(虽然栈的特性不推荐这么做)。
2. 缺点
  • 容量固定:初始化时必须指定最大容量(比如代码中的 maxsize=100),如果元素超过容量就会 “栈溢出”,无法动态扩容;
  • 内存浪费:如果实际存储的元素远少于 maxsize,数组中未使用的空间会造成浪费。
3. 应用场景

顺序栈适合元素数量固定、操作频繁的场景,比如:

  • 表达式计算:比如计算器处理括号、加减乘除的优先级,就会用栈来存储操作符;
  • 括号匹配:判断代码中括号是否成对出现(比如()、{}),遇到左括号入栈,遇到右括号出栈匹配;
  • 函数调用:程序执行函数时,会把函数的返回地址、参数等存入栈中,函数执行完再从栈中取出恢复现场。

五、总结

栈的顺序结构是数据结构入门的重要知识点,它的核心是 “数组 + 栈顶指针” 的组合,通过简单的指针移动实现 “后进先出” 的特性。今天我们从定义、核心操作、实际案例到应用场景,全方位拆解了顺序栈的知识,关键要点可以总结为:

  1. 顺序栈基于数组实现,核心是栈顶指针top的操作;
  2. 核心操作:初始化(top=-1)、入栈(top++)、出栈(top--)、查看栈顶(不修改 top);
  3. 特性:后进先出,适合需要 “逆序处理” 的场景;
  4. 优缺点:高效但容量固定,需根据实际场景选择使用。

如果你是编程新手,建议结合本文的代码案例,自己动手敲一遍代码,运行调试看看效果 —— 实践是掌握数据结构最好的方式。下一篇我们可以聊聊栈的另一种实现方式 —— 链式结构,看看它如何解决顺序栈容量固定的问题,感兴趣的小伙伴可以持续关注哦!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、什么是栈的顺序结构?
  • 二、顺序栈的核心操作(附代码解析)
    • 1. 栈的定义:用结构体封装数组和栈顶指针
    • 2. 初始化:给栈 “清空” 状态
    • 3. 入栈:往栈顶添加元素(压栈)
    • 4. 出栈:从栈顶删除元素
    • 5. 查看栈顶元素:只看不取
    • 6. 判断栈空:检查抽屉是否为空
  • 三、顺序栈的实际运行案例
  • 四、顺序栈的优缺点与应用场景
    • 1. 优点
    • 2. 缺点
    • 3. 应用场景
  • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档