目录
1 图的深入优先遍历伪代码及递归演示
前置准备:
回顾LeetCode 144/94/145/102号题目,二叉树的前序遍历、中序遍历、后序遍历和层序遍历
回顾589/590/429号题目,N叉树的前序遍历、后序遍历和层序遍历
1.1 二叉树前序遍历与图的前序遍历伪代码对比
先来一段算法的伪代码:
二叉树的深度优先遍历 | 图的深度优先遍历 |
preorderTraversal(root) | dfs(v) |
proorder(TreeNode node) { if(node != null) { List.add(node.val); preorder(node.left); preorder(node.right); } } |
bool[] visited = new bool[V]; preorder(int v) { visited[v] = 1; List.add[v]; foreach(int w in adjH[v]) { if(!visited[w]) { dfs[w]; } } } |
1.2 图的深度优先遍历递归过程推演
深度优先遍历执行过程为:
根据上述顺序,确定的遍历结果为:0-1-3-2-6-5-4
1.3 前序/后序遍历代码实现
后续优先遍历在有向图中有应用。
代码实现:
其中Graph类为上一篇博客文章中基于SortedSet实现的邻接表类,更换类名得到的。
class GraphDFS
{
Graph G;
private bool[] visit;//记录节点是否访问的数组
private List<int> pre; //前序遍历结果存储
private List<int> post; //后序遍历结果存储
public GraphDFS(Graph graph)
{
this.G = graph;
visit = new bool[G.VertexCount];
pre = new List<int>();
post = new List<int>();
//循环是为了处理存在多个联通分量的情形
for(int v = 0; v < G.EdgeCount; v++)
{
if(!visit[v])
{
dfs(v);
}
}
}
/// <summary>
/// 图的深度优先遍历
/// </summary>
/// <param name="v">要遍历的节点</param>
private void dfs(int v)
{
visit[v] = true;
pre.Add(v);
foreach (int w in G.getAdjEdge(v))
{
if (!visit[w])
{
dfs(w);
}
}
post.Add(v);
}
/// <summary>
/// 获取前序遍历列表
/// </summary>
/// <returns></returns>
public List<int> getPreResault()
{
return pre;
}
/// <summary>
/// 获取后序遍历列表
/// </summary>
/// <returns></returns>
public List<int> getPostResault()
{
return post;
}
/// <summary>
/// 打印遍历结果
/// </summary>
/// <param name="isPre">是否为前序遍历</param>
public void printResault(bool isPre)
{
if(isPre)
{
Console.Write("前序遍历结果:");
foreach(int v in pre)
{
Console.Write(s