数据结构----栈和队列

目录

  • 一、栈和队列的定义和特点
    • 1,栈的定义和特点
    • 2,队列的定义和特点
    • 3,栈和队列的典型案例
  • 二、栈的表现和实现
    • 1,栈的抽象数据类型定义
    • 2,栈的顺序表示
    • 3,顺序栈操作
    • 4,链栈表示和实现
    • 5,栈和递归
  • 三、队列的表示和实现
    • 1,队列的类型定义
    • 2,队列的顺序表示和实现
    • 3,队列的链式表示和实现

一、栈和队列的定义和特点

栈和队列时只能插入和删除在表的“端点”的线性表。
其中,栈是后进先出,只在表尾操作LIFO;队列是先进先出(FIFO),只在表尾插入(入栈push),只在表头删除 (出栈pop)。栈顶指向待存入数据的地址。
数据结构----栈和队列_第1张图片

1,栈的定义和特点

(1)栈的相关概念:
数据结构----栈和队列_第2张图片
(2)栈和一般线性表的区别:仅在于运算规则不同
数据结构----栈和队列_第3张图片

2,队列的定义和特点

队列的相关概念:
数据结构----栈和队列_第4张图片

3,栈和队列的典型案例

前三个为栈的案例,第四个是队列的案例。
(1)进制转换
用伤做被除数,每次将余数进栈,运行完之后依次出栈就达到了倒序的运算。
数据结构----栈和队列_第5张图片

(2)括号匹配的检验
遇到左括号就进栈,遇到右括号就跟当前栈顶匹配,能匹配就将其出栈,否则不匹配。
数据结构----栈和队列_第6张图片

(3)表达式求值
数据结构----栈和队列_第7张图片
数据结构----栈和队列_第8张图片
实际应用后续介绍
(4)舞伴问题
数据结构----栈和队列_第9张图片

二、栈的表现和实现

1,栈的抽象数据类型定义

数据结构----栈和队列_第10张图片
数据结构----栈和队列_第11张图片

2,栈的顺序表示

栈底为表头,栈顶为表尾。另设top和base指针分别指向顺序栈的栈底(低地址段端)和栈顶(为了方便,使top指向栈顶元素之上的下标位置)。stacksize为栈的最大容量。
base= =top是栈空标志。top-base==stacksize是栈满标志。满了之后top就溢出了,称为上溢。所以一般来说top-base都要小于stacksize。
数据结构----栈和队列_第12张图片
处理方法2很费时,所以一般不用。
空栈出栈也是溢出,称为下溢。上溢是一种错误,使问题的处理无法进行;而下溢一般认为是约束条件,即问题处理结束。
顺序栈简单方便,但容易溢出(数组大小固定)

3,顺序栈操作

数据结构----栈和队列_第13张图片
栈中元素个数:top-base
(1)顺序栈的初始化
数据结构----栈和队列_第14张图片
(2)判断是否为空
数据结构----栈和队列_第15张图片
top==base,空栈标志。
(3)求顺序栈的长度
数据结构----栈和队列_第16张图片
栈中元素个数:top-base
(4)清空顺序栈
无论栈中是否存在元素,直接让top指针指向base指向的空间,就认为空了。
数据结构----栈和队列_第17张图片
(5)销毁顺序栈
数据结构----栈和队列_第18张图片
直接删除base(将数组回归内存);再让stacksize设置为0,将base和top为空(结构类型中的三个值设置为空),即可释放空间。
(6)顺序栈入栈
在顺序栈非满栈的前提下,将元素入栈之后top+1。指针的*操作为取元素。
数据结构----栈和队列_第19张图片

(7)顺序栈出栈
栈非空的前提下,top-1之后再取栈顶元素。
数据结构----栈和队列_第20张图片

4,链栈表示和实现

指针方向是灵活变化的,根据需要自行调节。
数据结构----栈和队列_第21张图片(1)链栈初始化
数据结构----栈和队列_第22张图片
(2)链栈是否为空
数据结构----栈和队列_第23张图片
直接判断头指针是否为空

(3)链栈的入栈
对新的结点p分配空间并将新元素赋给data域之后,将头指针存放的头结点的地址放进新结点的next域;再将指针变量p的指赋值给s。
数据结构----栈和队列_第24张图片

(4)链栈的出栈
数据结构----栈和队列_第25张图片
将头结点的data域的值取出来,用指针p记录取出来的值之后,将头结点的next域赋给s即可。
(5)取栈顶元素
数据结构----栈和队列_第26张图片
栈非空的前提下,直接返回头结点的data域。

5,栈和递归

(1)递归的定义:
数据结构----栈和队列_第27张图片
(2)常用递归方法的情况

  1. 递归定义的数学函数:斐波拉契数列
  2. 具有递归特性的数据结构:二叉树,广义表
  3. 可递归求解的问题:迷宫问题,hanoi塔

(3)递归问题:分而治之
数据结构----栈和队列_第28张图片
数据结构----栈和队列_第29张图片
多个函数嵌套调用时,遵循后调用的先返回的原则,用栈实现。递归一定要用到栈。

数据结构----栈和队列_第30张图片
(4)递归的优缺点:
数据结构----栈和队列_第31张图片
对时间效率要求较高时,可把递归程序改成非递归程序:
数据结构----栈和队列_第32张图片
数据结构----栈和队列_第33张图片
数据结构----栈和队列_第34张图片
这里的主调函数也就是Fib(n)
数据结构----栈和队列_第35张图片
(5)利用栈改写递归的方法(了解)
数据结构----栈和队列_第36张图片
数据结构----栈和队列_第37张图片

三、队列的表示和实现

1,队列的类型定义

表尾插入,表头删除的线性表。
数据结构----栈和队列_第38张图片

2,队列的顺序表示和实现

(1)队列基本概念
front和rear只是表示位置的下标,不是指针结构。
数据结构----栈和队列_第39张图片
rear=maxsize时,溢出。此时若front不为0,则为假溢出,否则为真溢出。
解决假上溢,用循环队列。
(Q.rear+1)%maxsize的值在0~maxsize-1之间,当队列获取新元素时,(Q.rear+1)%maxsize的值就是下一个rear的地址,要么rear+1,要么是rear回到0的位置,达成循环。
数据结构----栈和队列_第40张图片
采用循环队列时,队空队满都是front=rear,怎么判断呢?
数据结构----栈和队列_第41张图片
此处使用方法三,则:(Q.rear+1)%maxsizefront时,代表队满。
front=rear代表队空==
(2)队列的初始化:
数据结构----栈和队列_第42张图片
数据结构----栈和队列_第43张图片
(3)队列的长度
数据结构----栈和队列_第44张图片
对于循环队列,(Q.rear-Q.front+maxsize)%maxsize为队列长度,对于普通队列可以直接Q.rear-Q.front
(4)循环队列入队
先判断队列是否为满,非满时可插入到rear指向的地址,再将rear加1。
数据结构----栈和队列_第45张图片
(4)循环队列出队
出队只能在表头删除,前提是队列非空。
数据结构----栈和队列_第46张图片
(5)取队头元素
队列非空时,直接返回队头指针元素,并且队头指针不变。对于删除(出队)操作,则是取出队头元素并且表头指针+1.

3,队列的链式表示和实现

无法估计所用队列的长度时,采用链队列。
(1)链队列的类型定义:
数据结构----栈和队列_第47张图片
(2)链队列的初始化
直接声明一个结点的内存空间,将front和rear指向这块空间,并且front的next域设置为null。
(3)链队列的销毁
从队头结点开始,依次释放所有结点。用一个过渡指针指向待删除结点(front处)的下一个结点,然后释放front,再将p所指地址赋给front;重复上述操作。(直接用现成的尾指针rear代替p,可以少用一个变量)
(4)将元素e入队
先将e放入一个结点空间p的data域,其next为null;然后rear->next=p,再将rear指向p所在节点(Q.rear=p)
(5)链队列出队

在队列非空的前提下,首先为指针变量p赋值,赋的是首元结点的地址,也就是p=Q.front->next;然后将p的data域给元素e,然后修改头结点next域(Q.front->next=p->next),然后删除结点p。
特殊情况,首元结点就是尾结点时,删除该节点之后还要修改尾指针的地址(头尾指针都指向头结点)。
(6)取队头元素
队列非空时,直接返回队头指针元素,并且队头指针不变。e=Q.front->next->data

你可能感兴趣的:(数据结构与算法分析,队列,数据结构,栈,链表,指针)