目录
- 图
- 基本定义
- 拓扑排序
本文包含王道考研讲课中所涉及的数据结构中的所有代码,当PPT代码和书上代码有所区别时以咸鱼的PPT为主,个人认为PPT上的代码比王道书上的代码要便于理解,此外,本博客也许会补充一些额外的代码进来(不仅受限于王道考研),408中冷门考点频出,应该会囊括所有涉及到的代码,这也是我的DS的第二轮复习,希望与大家共勉之。
DS的后四章只有最后一章(排序)涉及大量的代码,而树,图,查找这三章,对于概念的考察比较深入,故本文对于前三章也会进行概念上的整理,代码的话也同样会全部给出。
(2023/06/27)由于博客体量问题,本博客只会总结第六章【图】的知识点与代码
相关文章:
王道考研数据结构代码总结(前四章)
王道考研数据结构代码总结(第五章)
本文持续更新
图
基本定义
G : G r a p h G:Graph G:Graph(图); V : V e r t e x V:Vertex V:Vertex(顶点); E : E d g e E:Edge E:Edge(边)
图 G G G由顶点集 V V V和边集 E E E组成,记为 G = ( V , E ) G=(V,E) G=(V,E),其中 V ( G ) V(G) V(G)表示图 G G G中顶点的集合【非空】; E ( G ) E(G) E(G)表示图 G G G中边的集合。用 ∣ V ∣ |V| ∣V∣ 表示图 G G G 中顶点的个数,也称图 G G G的阶,用 ∣ E ∣ |E| ∣E∣ 表示图 G G G 中边的条数。
注:线性表可以是空表,树可以是空树,但图不可以是空,即 V V V 一定是非空集, E E E 则不做要求。
拓扑排序
逆拓扑排序:
// 逆拓扑排序的实现(DFS算法)
void DFSTraverse(Graph G){ // 对图G进行深度优先遍历
for (v = 0; v < G.vexnum; ++ v)
visited[v] = false; // 初始化已访问标记数据
for (v = 0; v < G.vexnum; ++ v) // 本代码中是从v=0开始遍历
if (!visted[v])
DFS(G, v);
/*
注意这里也是没被访问过直接DFS
这是因为第一个节点的DFS就会输出完一个连通分量
全部打印出去后,剩下的点和边也会是一个或多个连通分量,即会出现出度为0的 "线"
此时再次DFS即可
*/
}
void DFS(Graph G, int v){
visit(v); // 从顶点v出发,深度优先遍历图G
visited[v] = true; // 设已访问标记
/*
为什么不pop?
逆拓扑排序是先输出出度为0的点
所以只要有能往出走,就继续DFS即 if (!visited[w]) DFS(G, w);
故当不能往出走的时候,那么就是找见了出度为0的点
故我们需要打印输出,然后回溯
*/
for (w = FirstNeighbor(G, v); w >= 0; w = NextNeighor(G, v, w))
if (!visited[w]){ // w为u的尚未访问的邻接顶点
DFS(G, w);
}
print(v); // 打印顶点
/*
DFS实现逆拓扑排序:在顶点推栈前输出
此时的栈顶元素就是出度为0的点,符合我们的逆拓扑排序打印点的条件
逆拓扑排序打印点的条件:
1.找一个出度为0的点输出
2.删除该顶点和所有以它为终点的有向边
无法继续DFS就是找到了出度为0的点
打印顶点其实就相当于出栈,即删除这个结点和以它为重点的有向边
*/
}