3.1. 栈
3.1.1. 定义
后进先出
数学性质
n 个不同元素进栈,出栈元素不同排列的个数为
n+11(n2n)
3.1.2. 栈的形式
3.2. 队列
3.2.1. 定义
先进先出
3.2.2. 顺序存储结构
1. 顺序队列
- 队空:
Q.front == Q.rear == 0
- 入队:
if ( !Q.full() ) { Q.rear = x; Q.rear++; }
- 出队:
if ( !Q.empty() ) { int temp = Q.front; Q.front++; return temp; }
然而,这种队列存在假溢出的现象,需要进行改进。
2. 循环队列
- 初始:
Q.front == Q.rear == 0
- 队首指针进一:
Q.front = (Q.front + 1) % MaxSize
- 队尾指针进一:
Q.rear = (Q.rear + 1) % MaxSize
- 队列长度:
(Q.rear - Q.front + MaxSize) % MaxSize
此时,队空和队满的条件相同,难以区分。可以采用 “牺牲一个元素的位置” 来决定队列是否满。
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|
value | a | b | c | | | | | | | |
pointer | front | | | rear | | | | | | |
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|
value | a | b | | d | e | f | g | h | i | j |
pointer | | | rear | front | | | | | | |
- 队满条件:
(Q.rear + 1) % MaxSize == Q.front
- 队空条件:
Q.rear == Q.front
- 队列元素数量:
(Q.rear - Q.front + MaxSize) % MaxSize
其他方法,如增加一个 tag
表明是否满,均可。
3.2.4. 双端队列
3.3. 栈和队列的应用
3.3.4. 队列在层次遍历中的作用
- 根节点入队
- 若队空,则退出;否则重复下一步
- 队头出队,并访问它。将它的所有(未访问的)子节点添加到队尾。返回上一步
3.4. 数组和特殊矩阵
3.4.3. 特殊矩阵的压缩存储
- 压缩矩阵:为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间。目的是节省存储空间
- 特殊矩阵:具有许多相同矩阵元素或令元素,并且这些相同矩阵元素或零元素的分布有一定的规律性。常见的有对称矩阵、上(下)三角、对角阵等
1. 对称矩阵
a1,1a2,1⋮an,1a1,2a2,2⋮an,2⋯⋯⋱⋯a1,na2,n⋮an,n
用下三角区存储
只需要 n2n+1 个元素的空间,元素 a{i,j} 在数组中的索引
k=2i(i−1)+j−1,i⩾j
用上三角区存储
只需要 n2n+1 个元素的空间,元素 a{i,j} 在数组中的索引
k=2j(j−1)+i−1,i<j
2. 三角矩阵
将 A[1..n][1..n] 压缩存储在 B[n2n+1+1] 中,前面 n2n+1 个为数组元素,最后一个为常数 c
下三角
a1,1a2,1⋮an,1a2,2⋮an,2⋱⋯can,n
元素 a{i,j} 在数组中的索引
k=⎩⎨⎧2i(i−1)+j−1,2n(n+1),i⩾ji<j
上三角
a1,1ca1,2a2,2⋯⋯⋱a1,na2,n⋮an,n
元素 a{i,j} 在数组中的索引
k=⎩⎨⎧2(i−1)(2n−i+2)+(j−i),2n(n+1),i⩽ji>j
3. 三对角矩阵
a1,1a1,2a1,2a2,2a3,2a2,3a3,3⋱a3,4⋱an−1,n−2⋱an−1,n−1an,n−1an−1,nan,n
元素 a{i,j} 在数组中的索引
k=2i+j−3
3.4.4. 稀疏矩阵
使用三元组存储