有向圖基本遍歷算法


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 


發佈了13 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章