栈和队列

栈和队列的定义和特点

栈和队列是两种常用的、重要的数据结构

栈和队列是限定插入和删除只能在表的“端点”进行的线性表

由于栈的操作具有后进先出的固有特性,使得栈成为程序中的有用工具,另外,如果问题求解过程中具有“后进先出”的天然特性的话,则求解的算法中必然需要利用栈

【数制转换、括号匹配的检验、行编辑程序、迷宫求解、表达式求值、八皇后问题、函数调用、递归调用的实现】

队列:先进先出,插入在对位,删除在队头

栈的定义和特点

栈是一个特殊的线性表,是限定仅在一端(通常是表尾)

进行插入和删除操作的线性表

表尾称为栈顶,表头称为栈底

插入元素到栈顶的操作,称为入栈

从栈顶删除最后一个元素的操作,称为出栈

【栈(stack)的相关概念】

定义(限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作))

逻辑结构(与同线性表相同,仍为一对一关系)

存储结构(用顺序栈或链栈存储均可,但以顺序栈更常见)

运算规则(只能在栈顶运算,且访问结点时依照后进先出的原则)

实现方式(关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同)

【队列的定义和特点】

队列(quee)是一种先进先出的线性表。在表的一端插入(表尾)

在另一端(表头)删除

队列的相关概念

定义:只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表(头删尾插)

逻辑结构:与同线性表相同,仍为一对一关系

存储结构:顺序队或链队,以循环顺序队列更常见

运算规则:只能在队首和队尾运算,且访问节点时依照先进先出原则

实现方式:关键是掌握入队和出队操作,且具体实现依顺序队或链队的不同而不同。

栈的表示和操作的实现

由于栈本身就是线性表,于是栈也有顺序存储和链式存储两种实现方式

栈的顺序存储---顺序栈

image-20220330150857288

空栈:base==top是栈空标志

满栈:top-base==stacksize

满栈时的处理方法:
1.报错,返回操作系统

2.分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈

使用数组作为顺序栈存储方式的特点:
上溢:栈已经满,又要压入元素

下溢:栈已经空,还要弹出元素

上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束

栈的链式存储---链栈

image-20220331111608345

链栈式运算受限的单链表,只能在链表头部进行操作

链栈中指针域方向是后面指向前面

链表的头指针即使栈顶

不需要头结点

基本不存在栈满的情况

空栈相当于头指针指向空

插入和删除在栈顶处执行

栈与递归

递归的定义

若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的

若一个过程直接地或简介的调用自己,则称这个过程是递归的过程

函数调用过程

调用前,系统完成

(1)将实参,返回地址等传递给被调用函数

(2)为被调用函数的局部变量分配存储区

(3)将控制转移到被调用函数的入口

调用后,系统完成

(1)保存被调用函数的计算结果

(2)释放被调用函数的数据区

(3)依照被调用函数保存的返回地址将控制转移到调用函数

递归函数调用的实现

递归工作栈---递归程序运行期间使用的数据存储区

工作记录---实在参数,局部变量,返回地址

递归的优缺点

优点:结构清晰,程序易读

缺点:每次调用要生成工作记录,保存状态信息,入栈;返回时要出栈,恢复状态信息。时间开销大。

递归-->非递归

方法1:尾递归、单向递归->循环结构

方法2:自用栈模拟系统的运行时栈

借助栈改写递归

递归程序在执行时需要系统提供栈来实现

仿照递归算法执行过程中递归工作栈的状态变化可以写出相应的非递归程序

改写后的非递归算法与原来的递归算法相比,结构不够清晰,可读性较差,有的还需要经过一系列优化

队列的表示和操作的实现

队列是仅在表尾进行插入操作,在表头进行删除操作的线性表

表尾即an端,称为队尾;表头即a1端,称为队头

它是一种先进先出的线性表

插入元素称为入队,删除元素称为出队

队列的存储结构为链队或顺序队(常用循环顺序队)

队列初始:front=rear=0

空对标志:front==rear

队列的溢出:
【1】若front=0

rear=MAXQSIZE

再入队就是真溢出

【2】若front!=0

就是假溢出

解决办法:
【1】将队中元素依次向队头方向移动

缺点:浪费时间每移动一次,队中元素都要移动

【2】将队空间设想成一个循环的表,即分配给队列的m个存储单元可以循环使用,当rear为maxqsize时,若向量的开始端空着,又可从头使用空着的空间。当front为maxqsize时,也是一样。

解决假上溢的方法---引入循环队列

base[0]接在base[MAXQSIZE-1]之后,若rear+1=M,则令rear=0;

实现方法:利用摸(mod,c语言中:%)运算。

循环队列中无论是队空还是队满都是front==rear

解决办法:

【1】另外设一个标志以区别队空、队满

【2】另设一个变量,记录元素个数

【3】少用一个元素空间:

队空:front==rear

队满:(rear+1)%MAXQSIZE==front

链队

若用户无法估计所用队列的长度,则宜采用链队列

image-20220331212922000

front相当于头结点,头指针的下一个结点才是第一个存放数据的结点

posted @   我是一个大废物  阅读(253)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示