有向图基本遍历算法

1 图的表示

2. 有向图的遍历算法:深度优先

3. 有向图的遍历算法:广度优先

4 代码反思

5. 下载

1. 图的表示  

1.1 图的定义

图G定义为V和E的集合G={V, E},其中V表示图中的所有的顶点集合,E表示的是G中的所有的边的集合。图按照E中的元素是否有方向,分为有向图和无向图。 

1.2 图的表示方法

上面给出的数学上图的定义,那么在计算机中如何表示图?通常意义上,有下面的两种方法:邻接表和邻接矩阵表示法。

无向图的邻接表和邻接矩阵表示如下所示:

 《有向图基本遍历算法》

有向图的邻接表和邻接矩阵表示如下所示:

《有向图基本遍历算法》 

根据上面的表示方法,下面定义图G的这种数据结构(邻接表),首先定义图的顶点GraphVertex:

// 顶点显示的符号         public char Symbol { get; set; }                  // 顶点当前颜色         public VertexColor Color { get; set; }                  // 顶点和开始节点之间的距离         public int Distance { get; set; }                  // 广度遍历父节点         public GraphVertex Parent { get; set; }                  // 深度优先搜索中的开始时间         public int StartTime { get; set; }                  // 深度优先搜索中的结束时间         public int FinishTime { get; set; }         // 顶点对应的边

        public List<GraphEdge> FollowEdges { get; set; } 

定义图G的边的数据结构:

 
// 边开始顶点,在邻接表的存储中其实没有必要存储         public GraphVertex From { get; set; }         // 结束顶点         public GraphVertex To { get; set; }          // 边权重

        public int Weight { get; set; } 

定义图:

// 数据成员,这里假设的是顶点的symbol是各个不相同的         private Hashtable graph =              new Hashtable();

        private int time = 0; 

整体上的结构如下:

《有向图基本遍历算法》 

2. 有向图的深度优先算法 

2.1 基本算法

其中d表明的是某个节点第一次被发现的时间点,f表明从节点出发的全部节点已经被发现的时间。  

 《有向图基本遍历算法》

2.2 设计实现 

 
// 深度优先遍历算法         public void DepthFirstVisit(GraphVertex v)         {             // 刚刚被发现,颜色为gray             Console.WriteLine(v.Symbol);             v.Color = VertexColor.GRAY;             this.time++;             // 开始时间             v.StartTime = this.time;             foreach (GraphEdge edge in v.FollowEdges)             {                 // 还未被发现                 if (edge.To.Color == VertexColor.WHITE)                 {                     edge.To.Parent = v;                     DepthFirstVisit(edge.To);                 }             }                          // 如果边都已经发现完成             v.Color = VertexColor.BLACK;             this.time++;             v.FinishTime = this.time;                      }         public void DepthFirstTravel()         {             // 全局时间变量             this.time = 0;             // 初始化             GraphVertex v;             foreach (DictionaryEntry e in this.graph)             {                 v = (GraphVertex)e.Value;                 v.Color = VertexColor.WHITE;                 v.Parent = null;             }             // 递归调用             // 队所有的顶点             foreach (DictionaryEntry e in this.graph)             {                 v = (GraphVertex)e.Value;                 // 顶点为白色                 if (v.Color == VertexColor.WHITE)                 {                     DepthFirstVisit(v);                 }             }

        } 

3. 有向图的遍历算法:广度优先 

3.1 基本算法

其中color域表示的是当前某个节点被发现的状态。如果是white表明没有被发现,gray表示当前顶点已经被发现,但是从该节点出发的节点还没有被全部发现。parent域定义的是在搜索算法时父节点。distance域表明的是从节点s到某个发现的节点v的路径距离。

《有向图基本遍历算法》

3.2 设计实现 

// 广度优先遍历算法,同时生成广度优先树         public void BreadthFirstTravel(GraphVertex s)         {             // 初始化所有节点             GraphVertex v;             foreach (DictionaryEntry e in this.graph)             {                 v = (GraphVertex)e.Value;                 v.Color = VertexColor.WHITE;                 v.Distance = int.MaxValue;                 v.Parent = null;             }             // 发现第一个节点             s.Color = VertexColor.GRAY;             s.Distance = 0;             s.Parent = null;             // 初始化队列             Queue context =                  new Queue();             context.Enqueue(s);             // 如果队列不空的话             while (context.Count != 0)             {                 // 队首元素出队                 v = context.Dequeue() as GraphVertex;                 Console.WriteLine(v.Symbol);                 // 遍历v的节点                 foreach (GraphEdge item in v.FollowEdges)                 {                     if ( item.To.Color == VertexColor.WHITE)                     {                         item.To.Color = VertexColor.GRAY;                         item.To.Distance = v.Distance + 1;                         item.To.Parent = v;                         context.Enqueue(item.To);                     }                 }                 v.Color = VertexColor.BLACK;             }

        } 

4. 代码反思 

上面的搜索代码结构是比较典型的搜索结构:首先定义队列或者是栈来保存程序运行状态,如果容器不空,取出元素,然后对取出的元素做一些处理。 

5. 代码下载 

/Files/xuqiang/DirectedGraph1.rar 

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/u011823494/article/details/50803630
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞