文章目录
栈和队列
3.1_1栈的基本概念
1. 栈的定义
线性表是具有相同类的n个数据元素的有限序列。
栈是只允许在一端进行插入或删除操作的线性表
重要术语:栈顶 栈底 空栈
特点:LIFO 后进先出
2. 栈的基本操作
InitStack()
DestroyStack()
Push();
Pop();
GetTop();
3.常考题型
给出进栈顺序,求出栈顺序
4.小结
3.1_2栈的顺序存储
1.顺序栈的定义
typedef struct{
Elemtype data[maxsize];//静态数组存储栈中数据
int top; //栈顶指针
}
2. 进栈操作
bool push (SqStack &S,ElemType x)
{
}
3. 出栈操作
bool pop();
注意栈顶指针的意义
top是指向栈顶元素或栈顶元素的下一个
4.共享栈
typedef struct{
ElemType data[MaxSize];
int top0; //0号栈的栈顶指针
int top1;
}
两个栈共享一片空间
栈满的条件top0+1=top1
5. 小结
3.1.3 栈的链式存储的实现
1.链栈的定义
3.2_1队列的基本概念
1.队列的定义
队列是只运行在一端进行插入,在另一端删除的线性表
特性:先进先出 FIFO
重要术语:队头 队尾 空队列
2.队列的基本操作
InitQueue(&Q)
DeStroyQueue(&Q)
EnQueue(&Q,x);
DeQueue();
GetHead();
3.2_2队列的顺序存储的实现
1. 队列的顺实现
typedef struct{
Elemtype data[MaxSize];
int front,rear; //头指针与尾指针
}SqQueue;
rear=front 队列为空
2. 循环队列
rear=(rear+1)%MaxSize;
出队操作
Q.front==Q.rear //判断为空
Q.front=(Q.front+1)%MaxSize;
队列元素个数
(rear+MaxSize-front)%MaxSize;
可以通过定义一个size避免浪费(这不还是浪费了一个= =)
也可以通过一个tag,来表示最近进行的操作为删除还是插入
注意队尾指针的定义
3.2_3队列的链式实现
3.2_4 双端队列
1. 双端队列
判断输出序列合法性
卡特兰数 判断多少种合法出栈序列
3.3_1栈在括号匹配中的应用
1. 括号匹配
最后出现的左括号最先被匹配
思路 遇到左括号入栈,遇到右括号进去出栈
扫描到右括号且栈空,则失败
3.3_2栈在表达式求值中的应用
表达式的组成:操作数、运算符、界限符
1.中、后、前缀表达式
逆波兰表达式 后缀表达式 运算符在两个操作数后面
2. 这种缀转后缀
- 确定中缀运算符顺序
- 选择下一个运算符 安置【左操作数 右操作数 运算符】组合
- 如果右运算符没有被处理,则继续2
- 左优先原则
3.后缀表达式的计算
** 4.计算机实现后缀表达式**
5. 用栈从左到右扫描下一个元素
6. 若扫描到操作数测压入栈,并回到1
7. 若扫描到运算符,则弹出两个栈顶元素,执行相应运算
5.中缀转前缀
8. 确定中缀运算顺序
9. 选择 下一个运算符,安装【运算符 左操作数 右操作数】
10.如果还有没被处理的额运算符,则继续第二步
6.计算机实现前缀的运算
1 从右往左扫描
2 若扫描到操作数则压入栈,并回到1
3 若扫描到运算符,弹出并执行相应的运算
中缀表达式转后缀表达式(计算机)
中缀表达式的计算(用栈技术)
操作数栈:从做到右扫描,压入
运算符栈:按照中转转后缀的逻辑压入
3.3_4 栈在递归中的应用
函数调用的特性 LIFO
函数调用时,需要一个栈存储:
1 调用返回地址
2 实参
3 局部变量
适用用递归算法解决:可以把原始问题转换为属性相同,但规模较小的问题
3.3_5队列的应用
树的层次遍历
图的广度优先遍历
队列在操作系统中的应用:多个进程争抢着使用有限的额系统资源,FCFS(先来先服务)是一种常用策略
3.4 特殊矩阵的压缩存储
二维数组的存储结构:可以分为列优先与行优先
普通矩阵的存储
对称矩阵的压缩存储
需要存储(1+n)*n/2个数据
访问转换ai,j转换为aj,i
稀疏矩阵的压缩存储
顺序存储
Struct(i,j,value)