数据结构(3) ----------- 栈、队列

目录

1、基本概念

2、基本操作

3、顺序栈

3.1、创建

3.1、出入栈

3.2、共享栈

4、链栈

5、队列

5.1、基本操作

5.2、顺序实现

5.2.1、初始化

5.2.2、入队

5.2.3、出队

5.2.4、判空满

5.3、链式实现

5.3.1、初始化(带头节点)

5.3.2、入队

5.3.2、出队

5.3.3、判空满

5.4、双端队列

6、栈的应用

6.1、括号匹配

6.2、表达式求值

6.2.1、中缀表达式

6.2.2、后缀表达式

6.2.3、前缀表达式(在计算机中用的比较少)

6.3、递归调用

6.4、特殊矩阵(压缩存储)


1、基本概念

栈: 只允许先进后出的线性表;(相当于一个堆叠的结构,最先堆叠进入栈的元素只能最后才能取出来)

2、基本操作

3、顺序栈

3.1、创建

栈顶指针需要一直指向栈顶,用于控制出入栈。最开始栈中没有存放数据,栈指针指向空位置;

3.1、出入栈

进栈:

出栈:

3.2、共享栈

4、链栈

使用单链表实现的栈。(出入栈在链表头操作即可,具体定义和顺序栈一致)

5、队列

只允许在一端进行插入,在另一端删除的线性表。(先进先出)

5.1、基本操作

5.2、顺序实现

5.2.1、初始化

5.2.2、入队

5.2.3、出队

5.2.4、判空满

方案一:

判满:

若rear指针的下一个指针就是front则当前队列已满。(会牺牲一个存储空间)

判空:

若rear指针和front指针相遇。

方案二:

方案三:

5.3、链式实现

5.3.1、初始化(带头节点)

5.3.2、入队

带头节点:

不带头节点:

5.3.2、出队

带头节点:

不带头节点:

5.3.3、判空满

判满:

一般来说是不会满的;

判空:

将队列中的节点全部删光就空了;

5.4、双端队列

可以从两端插入和删除的队列。

例子:

其中输入序列意义为输入的顺序为1、2、3、4。

​​​

6、栈的应用

6.1、括号匹配

可以用于识别一串字符串中的括号是否匹配;

匹配规则:

实际结果:

1、若匹配后,栈中还有括号存在,则匹配不成功;

2、若匹配后,栈空则匹配成功;

实现:

6.2、表达式求值

6.2.1、中缀表达式

也就是平常所见的数学表达式。(eg.(a+b)*c - d)

6.2.2、后缀表达式

就是将运算符写在后面。要运算的两个变量写在前面。

中缀转后缀:

注:转表达式时要遵循左优先原则,以遵循算法输出结果的唯一性;

后缀表达式计算(也就是后缀转中缀):(从最里面的运算符开始两两相约)

后缀运算的计算机实际实现原理:(基于栈的原理实现后缀计算,很多基于栈的语言都是通过后缀表达式的方式来实现运算的)

运算过程:(计算机从左往右开始扫描)

1、首先扫描到A和B变量,并将其依次压入栈中;

2、扫描到+运算符时,就将A和B变量依次出栈,之后进行相加运算即可,运算后的结果再压入栈中;

3、扫描到CD两变量,依次压入栈中;

4、扫描到*运算符时,将CD两变量取出进行*运算,结果压入栈中;

5、扫描到E,将E压入栈中;

6、扫描到/运算符,之后将C*D的结果和E从栈中取出进行除运算,结果压入栈中;

7、扫面到-运算符,将栈中的两个元素进行-运算,运算结果压入栈底;

8、将F压入栈,扫描到+后,将栈底的结果和F进行+运算,最后的结果压入栈中,这个结果就是最终的结果;

中缀转后缀的计算机实际实现原理:

运算过程:(计算机从左往右开始扫描)

1、首先扫描到A将A直接输出,再扫描到+这时将+压入栈中;

2、扫描到B,将B直接输出,由于此时我们不知道有没有比+优先级更大的运算符,所以此时不动压入栈中的运算符+;

3、扫描到运算符*,虽然*的优先级>+,但此时我们要考虑后面有没有()的情况;

4、继续扫描到(,将(压入栈中;

5、输出C后,再次扫描到-,由于此时没有碰到)所以继续将-压入栈中;

6、输出D,扫描到)时,将()及其中间的运算符出栈,()中间的符号作为输出,也就是-

7、栈中有优先级更高的*运算符,将*输出,且在栈底的+也是和-优先级相等的,所以也进行一次输出(这里遵循的是按左优先原则),最后将-运算符压入;

8、输出E操作数,压入/运算符,扫描到F后输出F操作数,最后将/和-依次进行输出;

6.2.3、前缀表达式(在计算机中用的比较少)

就是将运算符写在前面。要运算的两个变量写在后面。

6.3、递归调用

在最外层递归return后(开始弹栈),就开始依次弹栈,最终输出193行的代码;

6.4、特殊矩阵(压缩存储)

先大致说明一下数组的存储方式:

1、行优先存储:

2、列优先存储类似。

普通矩阵存储:

对称矩阵压缩存储:

策略:

1、由于对称矩阵的上三角区和下三角区元素对称,所以我们只需要存储对角线以及其中一个三角区就能保存里面的所有信息了;

2、编写map映射函数,将矩阵的行列ij对应到数组的下标,其规则遵循:

3、上面是下三角区的情况(i>=j),若(i<j)则可以将j和i的位置调转后进行运算;

三角矩阵压缩存储:

策略:

1、将不是常量的那个三角区域的数据存储到一个一维数组中;

2、直接将常量使用一个空间进行存储;

3、使用映射函数,可以自己推导,下面是推导之后的公式;

上三角矩阵同理。

三对角矩阵(带状矩阵)的压缩存储:

策略:

特点:当 |i-j|<=1 时,就有ai,j = 0(1<=i,j<=n) ;

1、映射规律;(行优先原则)

2、已知k,如何求i,j?

稀疏矩阵压缩存储:

1、第一种压缩存储的方法: 顺序存储三元组(列出对应行列所对应的值)

2、第二种方法:十字链表法

1、每行指针对应矩阵的每列;

2、每列指针对应矩阵的每行;

3、若我要找行为1,列为6的元素,我就会访问列指针6和行指针1的指向。但情况会有两种:

  • 第六列直接访问到;
  • 第一行要遍历一次才能访问到;
相关推荐
一只小透明啊啊啊啊3 小时前
b树,b+树,红黑树
数据结构·b树·b+树
Mingze03143 小时前
C语言四大排序算法实战
c语言·数据结构·学习·算法·排序算法
程序员东岸4 小时前
学完顺序表后,用 C 语言写了一个通讯录
数据结构·笔记·学习
独自破碎E4 小时前
Leetcode2166-设计位集
java·数据结构·算法
Cikiss5 小时前
LeetCode160.相交链表【最通俗易懂版双指针】
java·数据结构·算法·链表
2301_789015626 小时前
算法与数据结构——排序算法大全
c语言·开发语言·数据结构·c++·算法·排序算法·visual studio
无限进步_7 小时前
冒泡排序的多种实现方式详解
c语言·数据结构·c++·算法
new coder8 小时前
[算法练习]Day 7: 变长滑动窗口
数据结构·算法·leetcode
2401_877274249 小时前
vector、list、deque的差异
数据结构·list