6.3 图的遍历
6.3.1 深度优先遍历
以下图为例,其深度优先遍历输出应该为:
1 -> 3 -> 2 -> 5 -> 4 -> 6 -> 7 -> 9 -> 8 -〉10
图的深度优先遍历类似于树的先序遍历,是树的先序遍历的推广。要借助一个辅助数组标记已经遍历过的顶点。
以邻接表为例实现图的深度优先遍历:GraphAdjList<T>类的定义在上一篇图的邻接表存储结构博客中
// public class GraphAdjList<T> : IGraph<T> public void Print() { Print(this.vexList, NodeNum); } public void Print(VexListNode<T>[] vexListNodes, int nodeNum) { bool[] markers = new bool[nodeNum]; //类似于二叉树的非递归深度优先遍历,借用一个stack实现 Stack<VexListNode<T>> stack=new Stack<VexListNode<T>>(); for (int i = 0; i < nodeNum; i++) { if (markers[i]) continue; stack.Push(vexListNodes[i]); while (stack.Count != 0) { VexListNode<T> currentVexListNode = stack.Pop(); GraphNode<T> node = currentVexListNode.Node; int vexIndex = IsNode(node); if (markers[vexIndex] == true) continue; Console.Write(node.Value + " "); markers[vexIndex] = true; AdjListNode<T> currentAdj=currentVexListNode.FirstAdj; while (currentAdj != null) { stack.Push(vexListNodes[currentAdj.AdjVexIndex]); currentAdj = currentAdj.Next; } } } }
6.3.2 广度优先遍历
图的广度优先遍历类似于树的层序便利
以下图为例,其广度优先遍历应该为:
1 -> 3 -> 4 -> 2-> 5 -> 6 -> 7 -> 9 -> 10 -> 8
以邻接表为例实现图的广度优先遍历:GraphAdjList<T>类的定义在上一篇图的邻接表存储结构博客中
// public class GraphAdjList<T> : IGraph<T> public void Print2() { Print2(this.vexList, NodeNum); } public void Print2(VexListNode<T>[] vexListNodes, int nodeNum) { bool[] markers = new bool[nodeNum]; //类似于二叉树的广度优先遍历,借用用一个queue实现 Queue<VexListNode<T>> queue = new Queue<VexListNode<T>>(); for (int i = 0; i < nodeNum; i++) { if (markers[i]) continue; queue.Enqueue(vexListNodes[i]); while (queue.Count != 0) { VexListNode<T> currentVexNode = queue.Dequeue(); GraphNode<T> node = currentVexNode.Node; int indexer = IsNode(node); AdjListNode<T> currentAdjNode = currentVexNode.FirstAdj; if (markers[indexer]) continue; Console.Write(node.Value); markers[indexer] = true; while (currentAdjNode != null) { queue.Enqueue(vexListNodes[currentAdjNode.AdjVexIndex]); currentAdjNode = currentAdjNode.Next; } } } }