1 栈的概念

  • 栈:限定仅在表尾进行插入和删除操作的线性表,后进先出的线性表,简称LIFO结构
  • 栈顶:表尾,允许插入和删除的一端
  • 栈底:表头,不允许插入和删除的一端
  • 空栈:不含任何数据元素的栈

2 栈的顺序存储结构

(1) 结构代码

typedef int SElemType
typedef struct
{SElemType data[MAXSIZE];int top;
}SqStack;

(2) 属性

从最底端0开始

(3) 操作

A 插入push:进栈

int Push(SqStack *S,SElemType e)
{if(S->top==MAXSIZE-1){ //栈满    return 0;}S->top++; //栈顶指针增加S->data[S->top]=e; //将新插入元素赋值给栈顶空间return 1;
}

B 删除pop:出栈

int Pop(SqStack *S,SElemType *e)
{if(S->top==-1){return 0;}*e=S->data[S->top]; //将要删除的栈顶元素赋值给eS->top--; //栈顶指针减1return 1;
}

C 进栈出栈有多种情况,只要保证是栈顶元素出栈就可以

3 栈的链式存储结构

(1) 结构代码

typedef struct StackNode
{SElemType data;struct StackNode *next;
}StackNode,*LinkStackPtr;typedef struct LinkStack
{LinkStackPtr top;int count;
}LinkStack;

(2) 操作

A 插入push:进栈

Status Push(LinkStack *S,SElemType e)
{LinkStackPtr p=(LinkStackPtr)malloc(sizeof(StackNode));p->data=e;p->next=S->top; //把当前的栈顶元素赋值给新结点的直接后继S->top=p; //将新的结点s赋值给栈顶指针S->count++;return OK;
}
 B 删除pop:出栈Status Pop(LinkStack *S,SElemType *e){LinkStackPtr p;if(StackEmpty(*S)){return ERROR;} *e=S->top->data;p=S->top; //将栈顶结点赋值给pS->top=S->top->next; //使得栈顶指针下移一位,指向后一结点free(p); //释放结点pS->count--;return OK;}C 判断栈为空int  empty_LinkStack(LinkStack*  top){if(top==null) return 1;     else  return  0;        }

*4 两栈共享空间
(1) 定义
一个栈增加,一个栈缩短,当top1+top2==top2时栈满

(2) 结构代码typedef struck{SElemType data[MAXSIZE];int top1;int top2;}SqDoubleStack;
(3) 操作A 插入push:进栈Status Push(SqDoubleStack *S,SElemType e,int stackNumber){if(S->top1+1==S->top2){ //栈已满,不能再push新元素了return ERROR;}if(stackNumber==1){ //栈 1 有元素进栈S->data[++S->top1]=e; //若是栈1则先top1+1后给数组元素赋值}else if(stackNumber==2){ //栈2有元素进栈S->data[--S->top2]=e; //若是栈2则先top2-1后给数组元素赋值}return OK;}B 删除pop:出栈Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber){if(stackNumber==1){if(S->top1==-1){return ERROR; //说明栈1已经是空栈,溢出}*e=S->data[S->top1--]; //将栈1的栈顶元素出栈 }else if(stackNumber==2){if(S->top2==MAXSIZE){return ERROR; //说明栈2已经是空栈,溢出}*e=S->data[S->top2++]; //将栈 2 的栈顶元素出栈 }return OK;}

5 栈的应用
(1) 递归
递归函数:一个直接调用自己或通过一系列的调用语句间接地调用自己的函数
(2) 将中缀表达式转化为后缀表达式
A 规则
l 从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,成为后缀表达式的一部分
l 若是符号,则判断其与栈顶符号的优先级,乘除优先加减
l 遇到(,将其入栈
l 遇到),将栈元素弹出,输出直到遇到(为止。只弹出并不输出
l 遇到任何其他的操作符,从栈中弹出所有比待压入元素优先级高的元素直到遇到更低优先级的元素(或者栈为空)(优先级相等也要弹出)为止
l 弹出完这些元素后,才将遇到的操作符压入到栈中。只有在遇到)的情况下我们才弹出(,其他情况我们都不会弹出(
l 读到了输入的末尾,则将栈中所有元素依次弹出
B 流程
l 中缀表达式9+(3-1)×3+10÷2转化为后缀表达式9 3 1 - 3 * + 10 2 / +
l 初始化一空栈,用来对符号进行出栈使用

     l 第一个字符是数字9,输出9,后面是符号+,进栈l 第三个字符是(,依然是符号,因其只是左括号,还未配对,故进栈l 第四个字符是数字3,输出,总表达式为9 3,接着是-,进栈l 接下来是数字1,输出,总表达式为9 3 1,后面是符号),此时,我们需要去匹配此前的(,所以栈顶依次出栈,并输出,直到(出栈为止。此时左括号上方只有-,因此输出-。总的输出表达式为9 3 1 -l 接着是数字3,输出,总的表达式为9 3 1 - 3。紧接着是符号×,因为此时的栈顶符号为+号,优先级低于×,因此不输出,*进栈l 之后是符号+,此时当前栈顶元素比这个+的优先级高,因此栈中元素出栈并输出(没有比+更低的优先级,所以全部出栈),总输出表达式为9 3 1 - 3 * +。然后将当前这个符号+进栈。也就是说,前6张图的栈底的+是指中缀表达式中开头的9后面那个+,而图中的栈底(也是栈顶)的+是指9+(3一1)×3+中的最后一个+l 紧接着数字10,输出,总表达式变为9 3 1 - 3 * + 10。后是符号÷,所以/进栈l 最后一个数字2,输出,总的表达式为9 3 1 - 3 * + 10 2l 因已经到最后,所以将栈中符号全部出栈并输出。最终输出的后缀表达式结果为9 3 1 - 3 * + 10 2 / +(3) 将后缀表达式进行运算得出结果A 规则从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果B 流程l 计算后缀表达式9 3 1 - 3 * + 10 2 / +l 初始化一个空栈。此栈用来对要运算的数字进出使用l 后缀表达式中前三个都是数字,所以9 3 1进栈l 接下来是-,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈l 接着是数字3进栈l 后面是*,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈l 下面是+,所以栈中6和9出栈,9与6相加,得到15,将15进栈l 接着是10与2两数字进栈l 接下来是符号/,因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈l 最后一个是符号+,所以15与5出栈并相加,得到20,将20进栈l 结果是20出栈,栈变为空

6 队列的概念
l 只允许在一端进行插入操作,而在另一端进行删除操作的线性表
l 队头:允许删除的一端
l 队尾:允许插入的一端
l 先进先出

7 队列的顺序结构
(1) 定义
l front指针指向队头元素,rear指针指向队尾元素的下一个位置,当front=rear时,成为空队列
l 为了防止假溢出,我们将队列收尾相接,形成一种特殊的顺序结构——循环队列
l 队列的最大尺寸为QueueSize
l 队列满的条件:(rear+1)%QueueSize==front
l 计算队列长度的公式:(rear-front+QueueSize)%QueueSize
(2) 结构代码
typedef int QElemType; /* QElemType 类型根据实际情况而定,这里假设为int /
/
循环队列的顺序存储结构 /
typedef struct
{
QElemType data[MAXSIZE];
int front; /
头指针 /
int rear; /
尾指针,若队列不空,指向队列尾元素的下一个位置 */
} SqQueue;
(3) 操作
A 初始化
/
初始化一个空队列 Q */
int InitQueue(SqQueue *Q)
{
Q->front=0;
Q->rear=0;
return 1;
}
B 求队列长度
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
C 入队
int EnQueue(SqQueue Q,QElemType e)
{
if ((Q->rear+1)%MAXSIZE == Q->front){ //队列满的判断
return 0;
}
Q->data[Q->rear]=e; //将元素e赋值给队尾
Q->rear=(Q->rear+1)%MAXSIZE; //rear指针向后移一位置
//若到最后则转到数组头部
return 1;
}
D 出队
int DeQueue(SqQueue Q,QElemType e)
{
if (Q->front == Q->rear){ //队列空的判断
return 0;
}
e=Q->data[Q->front]; //将队头元素赋值给e
Q->front=(Q->front+1)%MAXSIZE; //front指针向后移一位置
//若到最后则转到数组头部
return 1;
}
8 队列的链式结构
(1) 定义
队头指针指向链队列的头结点,队尾指针指向终端结点

(2) 结构代码typedef int QElemType; //QElemType 类型根据实际情况而定,这里假设为inttypedef struct QNode //结点结构{QElemType data;struct QNode *next;}QNode,*QueuePtr;typedef struct //队列的链表结构{QueuePtr front,rear; //队头、队尾指针} *LinkQueue;
*(3) 操作A 入队/*插入元素e为Q的新的队尾元素*/int EnQueue(LinkQueue Q,QElemType e){QueuePtr s=(QueuePtr)malloc(sizeof(QNode));if(!s){ //存储分配失败exit(-1);}s->data=e;s->next=NULL;Q->rear->next=s; //把拥有元素e的新结点s赋值给原队尾结点的后继Q->rear=s; //把当前的s设置为队尾结点,rear指向sreturn 1;}B 出队int DeQueue(LinkQueue Q,QElemType e){QueuePtr p;if(Q->front==Q->rear){return ERROR;}p=Q->front->next; //将欲删除的队头结点暂存给pe=p->data; //将欲删除的队头结点的值赋值给eQ->front->next=p->next; //将原队头结点的后继p->next赋值给头结点后继if(Q->rear==p){ //若队头就是队尾,则删除后将rear指向头结点Q->rear=Q->front;}free(p);return 1;}

9 队列的应用
l 汽车加油站
l 模拟打印机缓冲区

【数据结构】第三章 栈和队列相关推荐

  1. (王道408考研数据结构)第三章栈和队列-第三节1:栈的应用之括号匹配问题和表达式问题(前缀、中缀和后缀)

    前面我们就说过,栈是一种先进后出的线性表,这种先进后出的特性就决定了它在一类场合或问题中会经常被用到--递归.考研数据结构中所涉及的利用栈结构解决递归问题或者考察栈结构特性的问题主要有这么几类 括号匹 ...

  2. 数据结构-第三章-栈和队列(5)-链队

    数据结构 ⚡️数据结构-第一章 ⚡️抽象数据类型案例 ⚡️数据结构-第二章(1)-线性结构 ⚡️数据结构-第二章(2)-线性表的顺序表示和实现 ⚡️数据结构-第二章(3)-顺序表(含代码) ⚡️数据结 ...

  3. C语言数据结构-第三章栈和队列-电大同步进度

    第三章栈和队列简介 从数据结构角度看,栈和队列是两种重要的线性结构,是一类操作受限制的特殊线性表,其特殊性在于限制插入和删除等运算的位置. 堆栈,限制用户只能在指定的一端插入和删除元素,因此具有后进先 ...

  4. 王道考研408 数据结构 第三章 栈、队列与数组

    第三章 栈.队列与数组 3.1 栈 3.1.03 假设以I和O分别表示入栈和出栈操作.栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否则称为非法序 ...

  5. 王道数据结构课代表 - 考研数据结构 第三章 栈和队列 究极精华总结笔记

    本篇博客是考研期间学习王道课程 传送门 的笔记,以及一整年里对数据结构知识点的理解的总结.希望对新一届的计算机考研人提供帮助!!!   关于对 栈和队列 章节知识点总结的十分全面,涵括了<王道数 ...

  6. (王道408考研数据结构)第三章栈和队列-第一节:栈基本概念、顺序栈和链栈基本操作

    文章目录 一:栈基本概念 (1)栈的定义 (2)压栈和出栈 (3)进栈出栈变化形式 (4)栈的操作 二:栈的顺序存储结构及其操作实现 (1)顺序栈的定义 (2)进栈 (3)出栈 (4)读取栈顶元素 ( ...

  7. 数据结构——第三章 栈和队列

    一.单选题(共18题,55分) 1.栈结构通常采用的两种存储结构是( ).  A. 顺序存储结构和链表存储结构.  B. 散列方式和索引方式. C. 链表存储结构和数组.  D. 线性链表结构和非线性 ...

  8. 王道408数据结构——第三章 栈和队列

    一.栈 栈(Stack)是只允许在一端进行插入或删除操作的线性表. 栈顶:线性表允许插入删除的那一端 栈底:固定的.不允许进行插入删除的另一端 栈的操作特性可以概括为后进先出(LIFO) n个不同的元 ...

  9. (王道408考研数据结构)第三章栈和队列-第五节:Java、C++、Python实现栈和队列

    专栏目录首页:[专栏必读]王道考研408数据结构+计算机算法设计与分析万字笔记.题目题型总结.注意事项.目录导航和思维导图 文章目录 一:栈的实现 (1)C语言实现 (2)C++实现 (3)Java实 ...

  10. (王道408考研数据结构)第三章栈和队列-第二节:队列基本概念、顺序栈和链栈基本操作

    文章目录 一:队列基本概念 (1)队列的定义 (2)入队和出队 (3)队列的操作 二:队列的顺序存储结构(循环队列)及其操作实现 (1)单纯的顺序存储的不足之处及font指针和rear指针 (2)循环 ...

最新文章

  1. 逻辑覆盖测试(一)语句覆盖
  2. 陈天桥雒芊芊脑机接口中心等团队研究登顶刊:超声波“读心”
  3. HTML5从入门到精通(明日科技) 中文pdf扫描版
  4. python 签名计算 请求参数签名
  5. oracle用户登录的认证方式
  6. python 查找指定字符在字符串中的次数(全)
  7. webpack-dev-server详细教程(专治学不会)
  8. 2021牛客NOIP提高组第二场T2——方格计数(组合数计数)
  9. linux和windows下忘记mysql密码的几种找回方法
  10. 以太坊白皮书_以太坊发展历程
  11. emacs 安装指引
  12. rpm 完全卸载mysql
  13. 基于Rsoft的Beamprop模块进行光电子自聚焦透镜设计
  14. 禁用驱动数字签名验证
  15. 象棋( Xiangqi, ACM/ICPC Fuzhou 2011, UVa1589)
  16. 计算机鼠标右键的主要应用是什么原因,win7电脑桌面鼠标右键功能和作用|win7 64位桌面右键没反应,反应非常慢...
  17. 凑热闹,列个非主流书单:(1)分析与解决问题、通用管理(2)技术管理/CTO...
  18. SVD降维(相当好理解的文章)
  19. kubernetes节点减容与扩容
  20. NeXT,NEXTSTEP,OPENSTEP,Cocoa,Cocoa Touch,GNUstep,xcode

热门文章

  1. Linux-CentOS7.9系统rpm离线安装Oracle 19C
  2. 未来也许不一定只存在几种底层公链
  3. 双生林志玲-朱雯朱静
  4. 学校、社会团体完成阿里云账号实名认证的方法步骤
  5. angularjs 图片加载失败时,加载默认图片
  6. unity3d 为什么清晰的图片会变模糊
  7. 多线程编程CreateThread和_beginthreadex用法
  8. 邻接矩阵实现克鲁斯卡尔算法
  9. 非常【刑】又可【拷】的fiddler抓包实战 涵盖使用教程/下载安装/抓取手机app
  10. [转载]3GP文件格式研究