栈,线性表的一种特殊的存储结构。与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的。

图1 栈结构示意图

由于栈只有一边开口存取数据,称开口的那一端为“栈顶”,封死的那一端为“栈底”(类似于盛水的木桶,从哪进去的最后还得从哪出来)。

栈的“先进后出”原则

使用栈存储数据元素,对数据元素的“存”和“取”有严格的规定:数据按一定的顺序存储到栈中,当需要调取栈中某数据元素时,需要将在该数据元素之后进栈的先出栈,该数据元素才能从栈中提取出来。

如图 1 ,栈中存放了 4 个数据元素,进栈的顺序是 A 先进栈,然后 B 进,然后 C 进,最后 D 进栈;当需要调取 A 时,首先 D 出栈,然后 C 出栈,然后 B 出栈,最后 A 才能出栈被调用。

就好比只有一个门的车库(每次仅允许一辆车通过),每辆车好比一个数据元素,只有离门最近的车先开出来,里边的车才能出来;最里边的车是最先开进去的,注定要最后出来。

栈操作数据元素的方法

栈操作数据元素只有两种动作:

  1. 数据元素用栈的数据结构存储起来,称为“入栈”,也叫“压栈”。
  2. 数据元素由于某种原因需要从栈结构中提取出来,称为“出栈”,也叫“弹栈”。

栈的两种表示方式

既然栈也是线性表,那么它就同样有线性表的两种表示形式:顺序栈 和 链式栈(简称“链栈”)。

两者的区别在于存储的数据元素在物理结构上是否是相互紧挨着的。顺序栈存储元素预先申请连续的存储单元;链栈需要即申请,数据元素不紧挨着。

栈的“上溢”和“下溢”

栈存储结构调取栈中数据元素时,要避免出现“上溢”和“下溢”的情况:

“上溢”:在栈已经存满数据元素的情况下,如果继续向栈内存入数据,栈存储就会出错。

“下溢”:在栈内为空的状态下,如果对栈继续进行取数据的操作,就会出错。

栈的“上溢”和“下溢”,可以总结为:栈满还存会“上溢”,栈空再取会“下溢”。

对于栈的两种表示方式来说,顺序栈两种情况都有可能发生;而链栈由于“随时需要,随时申请空间”的存储结构,不会出现“上溢”的情况。

顺序栈

顺序栈的实现采用的是数组。

在顺序栈中设定一个随时指向栈顶元素的变量(一般命名为 top ),当 top 的值为 -1 时,说明数组中没有数据,即栈中没有数据元素,为“空栈”;只要数据元素进栈,top 就加 1 ;数据元素出栈, top 就减 1 。

例如,使用顺序栈的存储结构将(’a’,’b’,’c’,’d’)四个元素逐个压栈并输出栈顶元素。

实现代码:

#include <stdio.h>
//元素elem进栈
int push(char* a,int top,char elem){a[++top]=elem;return top;
}
//数据元素出栈
int pop(char * a,int top){if (top==-1) {printf("空栈");return -1;}printf("弹栈元素:%c\n",a[top]);top--;return top;
}
int main() {char a[100];int top=-1;top=push(a, top, 'a');top=push(a, top, 'b');top=push(a, top, 'c');top=push(a, top, 'd');top=pop(a, top);top=pop(a, top);top=pop(a, top);top=pop(a, top);top=pop(a, top);return 0;
}

输出结果:

弹栈元素:d
弹栈元素:c
弹栈元素:b
弹栈元素:a
空栈

链栈

链栈,用线性表的链式存储结构实现。

链栈一般不需要创建头结点,头结点会增加程序的复杂性,只需要创建一个头指针就可以了。

用链表表示栈时,用链表头结点的一端作为栈的栈顶端,这样做的好处是当数据元素压栈或者弹栈时,直接使用头指针就可以完成,不需要增设额外的指针。

例如,用链栈实现将(’a’,’b’,’c’,’d’)四个数据元素压栈,再依次弹栈:

#include <stdio.h>
#include <stdlib.h>
typedef struct lineStack{char data;struct lineStack * next;
}lineStack;
lineStack* push(lineStack * stack,char a){lineStack * line=(lineStack*)malloc(sizeof(lineStack));line->data=a;line->next=stack;stack=line;return stack;
}
lineStack * pop(lineStack * stack){if (stack) {lineStack * p=stack;stack=stack->next;printf("弹栈元素:%c ",p->data);if (stack) {printf("栈顶元素:%c\n",stack->data);}else{printf("栈已空\n");}free(p);}else{printf("栈内没有元素");return stack;}return stack;
}
int main() {lineStack * stack=NULL;stack=push(stack, 'a');stack=push(stack, 'b');stack=push(stack, 'c');stack=push(stack, 'd');stack=pop(stack);stack=pop(stack);stack=pop(stack);stack=pop(stack);stack=pop(stack);return 0;
}

输出结果:

弹栈元素:d 栈顶元素:c
弹栈元素:c 栈顶元素:b
弹栈元素:b 栈顶元素:a
弹栈元素:a 栈已空
栈内没有元素

总结

实际生活中使用手机时,屏幕页面的跳转使用的就是栈结构(跳转页面时,前一个页面会被存储到栈中;做回退操作时会回到上一个页面,这是进栈页面出栈的效果)。另外在求 n! 时,可以通过函数的递归来实现,这个过程的底层就用到了栈结构。

栈和队列:1.栈(Stack)相关推荐

  1. 八、【栈和队列】栈的应用

    栈的应用 栈具有先进后出的特点,这个特点在解决某些问题时是很有效的.本节我们来看几个栈的常见应用以及栈结构适合解决的问题类型. 1 数制转换 我们日常生活中用的是十进制,而计算机中绝大多数时候是二进制 ...

  2. Java中栈和队列的用法 Stack And Queue

    Java中栈和队列的用法 栈的实现 使用Java的集合类Stack boolean isEmpty();//判断当前栈是否为空,等价于empty(); synchronized E peek();// ...

  3. JavaSE(二十一)——栈和队列、栈和堆

    文章目录 1. 栈和队列 1.1 定义 1.2 区别 1.3 常见笔试题 2. 栈和堆 2.1 栈内存 2.2 堆内存 2.3 区别 1. 栈和队列 1.1 定义 栈(Stack):是限定能在表的一端 ...

  4. python 栈和队列_python 栈和队列的基本实现

    python中的列表结构可以用来实现栈和队列. [栈]: 栈是一种数据结构,具有先入后出的特点,并且栈的所有操作只能在某一端进行,能进行操作的一端的第一个元素称为栈顶,另一端的第一个元素称为栈底 栈的 ...

  5. java栈和队列_栈和队列的面试题Java

    栈和队列: 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min ...

  6. 数据结构之栈和队列以及如何封装栈和队列,栈和队列的实例(进制转换和击鼓传花)

    什么是数据结构? 不同的书对数据结构有不同的定义,例如: "数据结构是数据对象,以及存在于该对象的实例和 组成实例的数据元素之间的各种联系.这些联系可以通过定义相关的函数来给出." ...

  7. c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...

    第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...

  8. c语言中缀表达式求值_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)

    第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...

  9. 3.1栈和队列——顺序栈基本操作的实现

    注意:以下内容均省略思路,只有代码.此内容为本人学习过程中的一些学习记录,如有错误,恳请各位指正.建议,末学将感激不尽! 目录 1.前言 2. 栈的特点(计算机二级考试中常考的知识点) 3. 栈的应用 ...

  10. 栈和队列之栈的定义和实现

    栈的定义与实现 栈的定义:栈是限定在表尾进行插入或删除操作的线性表. 栈是一种特殊的线性表,栈只允许在线性表的一端进行操作. 1.栈顶(Top):允许操作的一端: 2.栈底(Bottom):不允许操作 ...

最新文章

  1. [置顶] 浅析objc的消息机制
  2. python使用方法-Python中bisect的使用方法
  3. PAT甲级题目翻译+答案 AcWing(链表)
  4. excel匹配_Excel中的数据匹配和查找
  5. php传二维数组,JS用POST怎么传送二维数组给PHP
  6. Pytorch cifar100离线加载二进制文件
  7. oracle redo 200mb,Oracle的redo log在各场景下的恢复
  8. 用Python写脚本:通过ssh在Windows下批量管理Linux
  9. 循迹传感器(TCRT5000)的介绍以及使用(STM32)
  10. 干货| PHPCon上TARS-PHP全面解读及PPT下载
  11. java手动调用finalize_Java并手动执行finalize
  12. C语言实现任意两种进制之间互相转换
  13. 1.3 收敛数列的性质
  14. 【证明】—— 矩阵秩的相关证明
  15. 数学建模之排队论模型及代码
  16. 数据科学 | Pandas新手入门
  17. 大学生期末考试Java复习题
  18. FPGA中的AXI总线知识点快速学习(适合新手)
  19. 宠物狗行走手机应用市场现状研究分析-
  20. 基于pandas实现K折交叉验证数据集划分

热门文章

  1. 台式机Windows 10系统打开或者断开网络的方法
  2. ROS 中文教程目录(最好不要过度依赖这种,建议养成看英文原版习惯)
  3. SQL Server MDS(主数据服务)介绍
  4. c++ 设计模式_设计模式行为型:观察者模式(ObserverPattern)
  5. 刘强东卸任京东集团CEO!接任人是他...
  6. 又出问题!特斯拉回应384万天价充电费:系统错误,正在修复
  7. iPhone 13及12推动,机构预计苹果今年将销售近2亿部5G iPhone
  8. 京东宣布全员涨薪两个月! 打工人流下了羡慕的泪水
  9. 一线城市夫妻“双城记”:带板凳上地铁,从江苏坐到江苏路站
  10. 华为Mate50系列不会停更:已敲定设计方案供货时间待定