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;
}
}
}
}