目录

  • 一、栈
    • (一)栈的概念
    • (二)栈的排列
    • (三)共享栈
    • (四)栈的常见应用
  • 二、顺序栈的定义
  • 三、顺序栈的初始化
  • 四、判断顺序栈是否为空栈
  • 五、判断顺序栈是否为满栈
  • 六、进栈(插入操作)
  • 七、出栈(删除操作)
  • 八、读取顺序栈顶元素
  • 九、顺序栈的建立
    • 一个简单的顺序栈的基本实现例子
  • 十、栈的遍历输出
  • 顺序存储结构实现栈的完整代码

一、栈

(一)栈的概念

  • 栈是一种只允许在一端进行插入或删除操作的线性表,它是一种特殊的线性表,它与队列具有相同的逻辑结构,都属于线性结构,区别在于对其中元素的处理不同,栈遵循的原则是先进后出(FILO),即后进的元素先被取出来,它是被限制存取点的线性结构。由于它是一种线性表,所以有两种方式:顺序存储结构和链式存储结构,即顺序栈链式栈

    其中,栈的插入操作称为进栈,栈的删除操作称为出栈

(二)栈的排列

根据栈的基本性质,对于n个不同数据元素执行进栈,出栈元素不同排列的个数为以下个数:

例如,三个不同的数据元素进栈,则1/(3+1)C36=1/4×20=5,即可以得到5种不同的出栈序列。

(三)共享栈

使用共享栈可以更加有效地利用存储空间,降低发生上溢的可能,通过让两个顺序栈共享一个一维数组空间,将这两个顺序栈的栈底分别设置在数组空间的两端,其中两个栈的栈顶指针都指向栈顶元素,当top1=-1时顺序栈1为空,当top2=MaxSize时顺序栈2为空,另外当两个栈顶指针相邻,即top2-top1=1时,此时共享栈满。

(四)栈的常见应用

栈的常见应用有以下:
(1)进制转换(例如十进制数转为二进制数等等);
(2)表达式求值(中后缀表达式、括号匹配等等);
(3)迷宫求解;
(3)递归(例如斐波那契数列等等)以及函数调用。

二、顺序栈的定义

顺序栈存储空间的实现是使用数组来存储栈元素的,通过一组数组地址的连续的存储单元来存放从栈底开始至栈顶的数据元素,同时设置一个栈顶指针top,用于指示当前栈顶元素的位置,代码如下:

#define MaxSize 20//可自行设置
typedef struct {int data[MaxSize];//存放栈中元素 ,使用数组int top;//栈顶指针 ,记录栈顶元素的位置
} SqStack;//顺序栈的类型定义

我们可以得到顺序栈的长度,由于数组下标是从0开始的,所以栈的长度为S.top+1,即要加1。顺序栈采用数组存储数据元素,由于数组的大小是固定的,不能动态分配大小,但链栈相比顺序栈的最大优势就是它可以动态地分配存储空间。

三、顺序栈的初始化

初始化一个顺序栈,这里的参数SqStack &S,带有“&”,表示引用调用,即对参数的修改结果进行带回,栈顶指针为S.top,栈顶元素的值为S.data[S.top],初始化时定义S.top=-1表示顺序栈为空,而当S.top=0时,表示栈中只存在一个元素,代码如下:

/*顺序栈的初始化,初始化一个空栈*/
void InitStack(SqStack &S) {S.top=-1;//顺序栈为空
}

四、判断顺序栈是否为空栈

可以得到,判断顺序栈是否为空栈的条件是S.top==-1,表示此时顺序栈中为空栈,无任何元素,代码如下:

/*判断顺序栈是否为空*/
bool StackEmpty(SqStack S) {if(S.top==-1)//当top=-1时,栈为空,而并不是S.top=0(它表示的是栈中有一个元素).return true;elsereturn false;
}

五、判断顺序栈是否为满栈

判断顺序栈是否为空栈的条件是S.top==MaxSize-1,由于c语言数组下标从0开始的,栈中元素最大个数MaxSize要减1,即当top=MaxSize-1时,表示此时顺序栈中已满,无法再存入元素,代码如下:

/*判断顺序栈是否为满栈*/
bool StackFull(SqStack S) {if(S.top==MaxSize-1)//由于c语言数组下标从0开始的,即当top=MaxSize-1时,此时栈满。return true;elsereturn false;
}

六、进栈(插入操作)

将一个元素插入顺序栈中,即进栈,首先应判断栈是否为满,即S.top==MaxSize-1,进栈的操作可以概括为指针先加1,然后再入栈,由于进栈后元素个数有变化,所以要用引用“&”,即SqStack &S,首先判断顺序栈是否已满,然后在新的元素进栈前,所以栈顶指针要先加1,即++S.top,然后将进栈元素的值传入并将其入栈,如下:

++S.top;//top指针始终指向栈顶,新的元素进栈,所以指针先加1
S.data[S.top]=x;//将进栈元素的值传入并入栈

这两行代码也可以使用一行代码:S.data[++S.top]=x直接替换。
进栈操作的完整代码如下:

/*进栈操作*/
bool StackPush(SqStack &S,int x) {if(S.top==MaxSize-1)//若栈已满,则报错return false;++S.top;//top指针始终指向栈顶,新的元素进栈,所以指针先加1S.data[S.top]=x;//将进栈元素的值传入并入栈//S.data[++S.top]=x;return true;
}

七、出栈(删除操作)

将一个元素从顺序栈中删除,即出栈,首先应判断栈是否为空,即S.top==-1,出栈的操作可以概括为先出栈,然后指针再减1,由于栈的特性,只能先进后出,即从栈顶进行删除操作然后依次,同样出栈后元素个数有变化,所以要用引用“&”,即SqStack &S,首先判断顺序栈是否为空,元素出栈后(将栈顶元素赋给x),然后栈顶指针要减1,如下:

x=S.data[S.top];//出栈
S.top--;//指针减1

这两行代码也可以使用一行代码:x=S.data[S.top--]直接替换。
出栈操作的完整代码如下:

/*出栈操作*/
bool StackPop(SqStack &S,int x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//出栈S.top--;//指针减1//x=S.data[S.top--];return true;
}

八、读取顺序栈顶元素

读取顺序栈顶元素,这里并没有将栈顶元素取出(无出栈操作),首先判断当前顺序栈是否为空,然后通过x来记录栈顶元素,如下:

/*读取栈顶元素*/
bool StackGetTop(SqStack S,int &x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//x记录栈顶元素return true;
}

九、顺序栈的建立

顺序栈的建立中输入一个值代表要创建的栈的元素个数,然后通过一个for循环建立顺序栈,其中使用到栈的进栈操作,每次向栈中插入元素,代码如下:

/*栈的建立*/
void CreateStack(SqStack &S,int x){int number;printf("请输入要建立栈的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);StackPush(S,x);}
}

一个简单的顺序栈的基本实现例子

例如,创建一个顺序栈,栈中元素从栈底到栈顶依次为1,2,3,4,5,第一步首先输出当前栈顶元素;第二步通过用户输入一个要进栈的元素“6”,并输出进栈后此时的栈顶元素;第三步通过执行一次出栈操作后,然后再输出此时的栈顶元素。
实现代码如下:

#include<stdio.h>
#define MaxSize 20//可自行设置
typedef struct {int data[MaxSize];//存放栈中元素 ,使用数组int top;//栈顶指针 ,记录栈顶元素的位置
} SqStack;//顺序栈的类型定义/*顺序栈的初始化,初始化一个空栈*/
void InitStack(SqStack &S) {S.top=-1;//顺序栈为空
}/*判断顺序栈是否为空*/
bool StackEmpty(SqStack S) {if(S.top==-1)//当top=-1时,栈为空,而并不是S.top=0(它表示的是栈中有一个元素).return true;elsereturn false;
}/*判断顺序栈是否为满栈*/
bool StackFull(SqStack S) {if(S.top==MaxSize-1)//由于c语言数组下标从0开始的,即当top=MaxSize-1时,此时栈满。return true;elsereturn false;
}/*进栈操作*/
bool StackPush(SqStack &S,int x) {if(S.top==MaxSize-1)//若栈已满,则报错return false;++S.top;//top指针始终指向栈顶,新的元素进栈,所以指针先加1S.data[S.top]=x;//将进栈元素的值传入并入栈//S.data[++S.top]=x;return true;
}/*出栈操作*/
bool StackPop(SqStack &S,int x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//出栈S.top--;//指针减1//x=S.data[S.top--];return true;
}/*读取栈顶元素*/
bool StackGetTop(SqStack S,int &x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//x记录栈顶元素return true;
}/*栈的建立*/
void CreateStack(SqStack &S,int x) {int number;printf("请输入要建立栈的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);StackPush(S,x);}
}/*主函数*/
int main() {SqStack S;int x,e;InitStack(S);//初始化CreateStack(S,x);//创建顺序栈StackGetTop(S,x);//读取栈顶元素printf("读取栈顶元素,当前栈顶元素为:%d\n",x);printf("输入一个要进栈的元素:");scanf("%d",&e);StackPush(S,e);//进栈StackGetTop(S,x);printf("读取栈顶元素,当前栈顶元素为:%d\n",x);StackPop(S,x);//出栈StackGetTop(S,x);printf("执行一次出栈操作后,当前栈顶元素为:%d",x);
}

运行结果如下:

十、栈的遍历输出

首先判断顺序栈是否为空,然后通过while循环,当S.top!=-1时一直执行下去,每次输出栈顶的元素,然后再减1,如下代码:

/*栈的遍历输出*/
bool PrintStack(SqStack S,int x){if(S.top==-1)//若栈为空,则报错return false;while(S.top!=-1){x=S.data[S.top--];printf("%d ",x);}return true;
}

例如,下列代码:

#include<stdio.h>
#define MaxSize 20//可自行设置
typedef struct {int data[MaxSize];//存放栈中元素 ,使用数组int top;//栈顶指针 ,记录栈顶元素的位置
} SqStack;//顺序栈的类型定义/*顺序栈的初始化,初始化一个空栈*/
void InitStack(SqStack &S) {S.top=-1;//顺序栈为空
}/*判断顺序栈是否为空*/
bool StackEmpty(SqStack S) {if(S.top==-1)//当top=-1时,栈为空,而并不是S.top=0(它表示的是栈中有一个元素).return true;elsereturn false;
}/*判断顺序栈是否为满栈*/
bool StackFull(SqStack S) {if(S.top==MaxSize-1)//由于c语言数组下标从0开始的,即当top=MaxSize-1时,此时栈满。return true;elsereturn false;
}/*进栈操作*/
bool StackPush(SqStack &S,int x) {if(S.top==MaxSize-1)//若栈已满,则报错return false;++S.top;//top指针始终指向栈顶,新的元素进栈,所以指针先加1S.data[S.top]=x;//将进栈元素的值传入并入栈//S.data[++S.top]=x;return true;
}/*出栈操作*/
bool StackPop(SqStack &S,int x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//出栈S.top--;//指针减1//x=S.data[S.top--];return true;
}/*读取栈顶元素*/
bool StackGetTop(SqStack S,int &x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//x记录栈顶元素return true;
}/*栈的建立*/
void CreateStack(SqStack &S,int x) {int number;printf("请输入要建立栈的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);StackPush(S,x);}
}/*栈的遍历输出*/
bool PrintStack(SqStack S,int x){if(S.top==-1)//若栈为空,则报错return false;while(S.top!=-1){x=S.data[S.top--];printf("%d ",x);}return true;
} /*主函数*/
int main() {SqStack S;int x;InitStack(S);//初始化CreateStack(S,x);//创建顺序栈StackGetTop(S,x);//读取栈顶元素printf("读取栈顶元素,当前栈顶元素为:%d\n",x);printf("从栈顶到栈底的元素(出栈顺序)依次为:");PrintStack(S,x); //遍历输出栈中元素
}

运行结果如下:

顺序存储结构实现栈的完整代码

链式存储结构实现栈的完整代码如下:

#include<stdio.h>
#define MaxSize 20//可自行设置
typedef struct {int data[MaxSize];//存放栈中元素 ,使用数组int top;//栈顶指针 ,记录栈顶元素的位置
} SqStack;//顺序栈的类型定义/*顺序栈的初始化,初始化一个空栈*/
void InitStack(SqStack &S) {S.top=-1;//顺序栈为空
}/*判断顺序栈是否为空*/
bool StackEmpty(SqStack S) {if(S.top==-1)//当top=-1时,栈为空,而并不是S.top=0(它表示的是栈中有一个元素).return true;elsereturn false;
}/*判断顺序栈是否为满栈*/
bool StackFull(SqStack S) {if(S.top==MaxSize-1)//由于c语言数组下标从0开始的,即当top=MaxSize-1时,此时栈满。return true;elsereturn false;
}/*进栈操作*/
bool StackPush(SqStack &S,int x) {if(S.top==MaxSize-1)//若栈已满,则报错return false;++S.top;//top指针始终指向栈顶,新的元素进栈,所以指针先加1S.data[S.top]=x;//将进栈元素的值传入并入栈//S.data[++S.top]=x;return true;
}/*出栈操作*/
bool StackPop(SqStack &S,int x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//出栈S.top--;//指针减1//x=S.data[S.top--];return true;
}/*读取栈顶元素*/
bool StackGetTop(SqStack S,int &x) {if(S.top==-1)//若栈为空,则报错return false;x=S.data[S.top];//x记录栈顶元素return true;
}/*栈的建立*/
void CreateStack(SqStack &S,int x) {int number;printf("请输入要建立栈的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);StackPush(S,x);}
}/*栈的遍历输出*/
bool PrintStack(SqStack S,int x){if(S.top==-1)//若栈为空,则报错return false;while(S.top!=-1){x=S.data[S.top--];printf("%d ",x);}return true;
} /*输出栈的元素个数*/
bool LengthStack(SqStack S,int length){if(S.top==-1)//若栈为空,则报错return false;length=S.top+1;printf("%d",&length);return true;
}/*栈的遍历输出*/
bool PrintStack(SqStack S,int x){if(S.top==-1)//若栈为空,则报错return false;while(S.top!=-1){x=S.data[S.top--];printf("%d ",x);}return true;
}

数据结构学习笔记——栈的基本知识和顺序存储结构实现栈(顺序栈)相关推荐

  1. 数据结构学习笔记(五):重识字符串(String)

    目录 1 字符串与数组的关系 1.1 字符串与数组的联系 1.2 字符串与数组的区别 2 实现字符串的链式存储(Java) 3 子串查找的简单实现 1 字符串与数组的关系 1.1 字符串与数组的联系 ...

  2. 数据结构学习笔记:实现链表

    数据结构学习笔记:实现链表 1.结点结构 结点结构是由数据域和指针域组成,数据域是存放数据的,而指针域存放下一结点的地址. 2.链表结构 通过数据域访问到我们要的数据,而通过指针域访问到当前结点以后的 ...

  3. 数据结构——课堂笔记【上课重点知识截图】

    文章目录: 考纲分析: 各个学校考纲: 第一章:绪论 第一节:基本概念 1.数据项-数据元素-数据对象 2.数据结构 2.1 逻辑机构[线性结构-集合-树形结构-图形结构] 2.2 物理结构 3.数据 ...

  4. Python数据结构学习笔记——栈

    目录 一.栈的定义和特性 (一)栈的定义 (二)栈的反转特性 二.实现分析步骤 三.栈的Python实现代码 四.栈的应用 (一)匹配圆括号 (二)匹配符号 (三)模2除法(十进制转二进制) (四)进 ...

  5. 数据结构学习笔记:利用栈实现进制转换

    数据结构学习笔记:利用栈实现进制转换 一.除基倒取余法示意图 二.编写十进制转换成二进制Python程序 1.源代码 2.运行结果 其实Python提供了一

  6. 数据结构学习笔记:利用Python列表实现栈结构

    数据结构学习笔记:利用Python列表实现栈结构 利用Python列表实现栈结构.有两种实现方式: 1.将列表的末尾(rear)作为栈顶(top) 2.将列表的前端(front)作为栈顶(top) 一 ...

  7. 数据结构学习笔记(六):二叉树(Binary Tree)

    目录 1 背景知识:树(Tree) 2 何为二叉树(Binray Tree) 2.1 二叉树的概念与结构 2.2 满二叉树与完全二叉树 2.3 二叉树的三种遍历方式 3 二叉树及其遍历的简单实现(Ja ...

  8. 数据结构学习笔记(四):重识数组(Array)

    目录 1 数组通过索引访问元素的原理 1.1 内存空间的连续性 1.2 数据类型的同一性 2 数组与链表增删查操作特性的对比 2.1 数组与链表的共性与差异 2.2 数组与链表增删查特性差异的原理 3 ...

  9. 考研[*数据结构*]学习笔记汇总(全)

    文章目录: 一:预备阶段 二:基础阶段笔记 三:冲刺阶段笔记 四:各章节思维导图 五:题库 来源:王道计算机考研 数据结构 一:预备阶段 之前的数据结构笔记 数据结构--学习笔记--入门必看[建议收藏 ...

最新文章

  1. MVC架构 在Android中的使用
  2. cam db num
  3. Tensorflow学习
  4. 花里胡哨?一起来看看 PyCharm 2019.3 增加了哪些新功能吧
  5. Java中的ClassLoader
  6. mysql innodb表损坏_MySQL数据库INNODB表损坏修复处理过程分享
  7. Python3 局部变量与全局变量作用域
  8. 暑假周进度总结报告4
  9. PHP中输出本地时间
  10. Douglas Peucker算法的C#实现
  11. 计算机excel怎么添加实线边框,excel加数据表格线-如何在excel中给数据加上实线外部及内部边框...
  12. linux 限制进程网速,Linux限制网速
  13. html颜色奶白色,象牙白rgb值是多少 和乳白哪个更白
  14. 验证数据是否满足正态分布——Q-Q图和P-P图
  15. 谈谈你对 Webpack 的理解
  16. 排座系统c语言,2008noip排座位C语言详解.doc
  17. ios11更新提示信任_iPhone手机iOS11怎么设置信任软件
  18. 【记录贴】AD21将元素复制到KeepOutLayer层的方法
  19. 手把手教你软件著作权申请表填写
  20. COLA 2.0架构应用

热门文章

  1. oracle中sql函数exists,sql的exits函数
  2. 【Jailhouse 文章】Look Mum, no VM Exits
  3. Android解决三星手机图片旋转问题
  4. C++ ifstream
  5. 牛根生的企业家生涯到头了
  6. centos 6.4 NTP服务器的搭建过程
  7. 快速分析出德邦快递揽收后没有物流的单号
  8. 台式机如何内外网同时上(笔记本同理,笔记本可以连WiFi)
  9. 【毕业设计】基于ssm的演唱会订票管理系统,订票管理系统,网上演唱会票务系统,票务管理系统,附源码+文档+PPT
  10. 计算机网络端口聚合实验,《计算机网络实验报告》5_端口聚合实验.pdf