数据结构复习
1.栈
栈可以用多种方法实现:
- 数组+计数器(记录栈容量)
- 标准库中的
Vector
容器 - 链表+计数器
- 标准库中的
Stack
数据结构
栈的应用:
括号匹配
括号入栈前与栈顶括号比较,若匹配则栈顶元素弹出,否则继续入栈。
设计链栈
注意栈的
pop
和push
操作都是在表头进行。设计支持返回栈中最大值的栈
使用辅助栈存储当前栈中的最大值。当入栈元素大于辅助栈栈顶元素时将该元素也压入辅助栈;当要弹出的栈顶元素等于辅助栈栈顶元素时,2个栈顶元素都弹出。
后缀表达式计算
数字入栈,遇到运算符号时取出栈顶2个元素完成运算并将结果入栈直至得到最终结果。
BST中序遍历
BST结点入栈,遇到没有子结点的栈顶元素时连续弹出2个栈顶元素。
记录Hanoi Tower移动
进制转换
将转换(先
%
运算再/
运算)后的低位数依次,最后依次出栈完成转换。
2.队列
队列可以用多种方法实现:
- 数组+计数器(记录队列容量)
- 标准库中的
Queue
容器
-数组(环状数组实现)+队头下标+队尾下标+计数器
队列的应用:
回文判断
字符串分别放入队列和栈,然后依次出栈和出队列,比较2个元素是否相同。
使用双栈模拟队列
一个栈负责
pop
,另一个栈负责push
。BST的广度有限搜索
依次将结点放入队列,然后按照队列中的顺序将该结点的子结点依次放入新的队列,并将该结点出队。
3.链表
链表直接使用基于指针的结构体进行构建。
struct Node{
void* value;
Node* leftSub;
Node* rightSub;
void* otherInfo;
};
链表的应用:
基数排序
生成编号为0到9这10个链表,然后自数字的低位到高位不断刷新链表内容,最后按照编号从小到大输出链表中的值,即可完成升序排列。
判断单向链表是否有环
设置2个指针(一个慢指针、一个快指针)对该链表进行遍历,如果遇到2个指针重叠,那么该链表存在环(证伪不证实)。
翻转链表
遍历原始链表,同时新建链表,将每次遍历到的结点更新为新链表的头结点。
有序链表去重
判断相邻结点是否相同,相同则删除其中一个结点。
有序链表合并
依次遍历,(以升序为例)比较2个链表的当前结点谁小取谁放入新的链表,然后比较后一结点。
倒数第k个结点
使用2个指针,快指针先遍历k个结点,再和慢指针一起遍历,当快指针访问到链表尾部NULL时,慢指针的位置就是倒数第k个结点。
2个单链表中相同结点的检查
尾结点相同,则2个单链表中存在相同结点。
4.散列表Hash Table
散列表包含2个重点:
- 散列函数
1.直接定址
2.除留余数
3.平方取中
4.折叠法(针对位数较多的关键码)
5.数字分析
6.随机数
- 冲突处理
1.开放地址法 Open Addressing
(1)线性探查 Linear Probing
(2)二次探查 Quadratic Probing
2.分块链接 Chaining
(1)链地址
(2)拉链法
5.树与二叉搜索树
树tree
的关键概念:
path
:从root出发由上而下,结点之间存在的遍历路径。length
:path
的长度。depth
:leaf
结点到root
结点的最长path
中的边个数。height
:leaf
结点到root
结点的最长path
中的结点个数。level
:结点到root
的路径长度。
树的性质:
complete
:每一个结点,要么没有子节点,要么有左右2个结点。balanced
:左右子树的height
相同。
二叉搜索树BST的3种遍历顺序(形成3种表达式):
- 前序遍历
pre-oder
- 中序遍历
in-order
- 后序遍历
post-order
有关树的问题
AVL平衡树的结点插入与平衡旋转
森林
Forest
的遍历森林
Forest
的并查集Disjoint-Set
6.图Graph
图的组成
G={V,E}
其中V
表示点vertex
组成的集合,E
表示边edge
组成的集合。
e=(v,w)
其中v
和w
是2个点,e
是由v
和w
为端点构成的边。那么,称边e
和点v
、w
是邻接Incident
关系;称点v
和w
是相邻Adjacent
关系。
path
:相邻关系的点及其边构成的集合。cycle
:path
是一个圆环。degree
:与一个点相邻的点的个数(也是与一个点邻接的边的条数)。
图的性质
connected
:任意点对之间都存在边。
对于一个digraph
,strongly connected
强连通是指考虑方向时,图是connected
连通的;weakly connected
弱连通是指不考虑方向时,剩下的无向图是connected
连通的。free
:图中不存在环。dense
稠密与sparse
稀疏:当边数与点数相近时,称为dense
稠密图;当边数<<点数时,称为sparse
稀疏图。simple graph
:不存在多重边的图。Directed Acyclic Graph
:有向无环图DAG
图的遍历
- 深度优先遍历
Depth-First
void DF(Node* n)
{
if(n == NULL)
{
//Stop searching
}
current_node_set_visited();
display_current_node();
DF(n->lson);
DF(n->rson);
}
- 广度优先遍历
Breadth-First
void BF(Node* root)
{
queue<Node> oldQueue;
oldQueue.push(root);
while(!oldQueue.empty())
{
queue<Node> tempQueue;
for(int i = 0; i < oldQueue.size(); i++)
{
InsertToTempQueue((*(oldQueue.front().lson)));
InsertToTempQueue((*(oldQueue.front().rson)));
displayNodeInfo(oldQueue.front());
oldQueue.pop();
}
oldQueue = tempQueue;
}
}
图的应用
最短路径
Shortest Path
(1)不带权重的图:Breadth-First Searching (2)带权重的图:Dijkstra's Algorithm
最小生成树
Minimal Spanning Tree
(1)Prim's Algorithm (2)Kruskal's Algorithm
图的并查集操作
Disjoint-Set Operation
拓扑排序
Topological Sort
搜索连通分支
Connected Component