第75课 - 图的遍历(DFS)

1、图的遍历(DFS)

        深度优先(DFS) 

    《第75课 - 图的遍历(DFS)》

        深度优先算法 

            -原料:
class
LinkStack<
T>; 

            –  步骤 

                    1. 将起始顶点压入栈中 

                    2. 弹出栈顶顶点V, 判断是否已经标记(标记:转2, 未标记:转3) 

                    3. 标记顶点,并将顶点v的邻接顶点压入栈中 

                    4 判断栈是否为空(非空:
转2, 空:结束)

        深度优先算法示例 

            《第75课 - 图的遍历(DFS)》

                《第75课 - 图的遍历(DFS)》

2、编程实验 

深度优先算法     Graph::DFS 

Graph.h

新增

  1. SharedPointer< Array<int> > DFS(int i)  
  2. {  
  3.     DynamicArray<int>* ret = NULL;  
  4.   
  5.     if((0 <= i)&&(i < vCount()))  
  6.     {  
  7.         LinkStack<int> s;  
  8.         LinkQueue<int> r;  
  9.         DynamicArray<bool> visited(vCount());  
  10.   
  11.         for(int j=0;j<visited.length();j++)  
  12.         {  
  13.             visited[j] = false;  
  14.         }  
  15.   
  16.         s.push(i);  
  17.   
  18.         while(s.size() > 0)  
  19.         {  
  20.             int v = s.top();  
  21.   
  22.             s.pop();  
  23.   
  24.             if( !visited[v] )  
  25.             {  
  26.                 SharedPointer< Array<int> > aj = getAdjacent(v);  
  27.   
  28.                 for(int j=aj->length()-1;j>=0;j–)  
  29.                 {  
  30.                     s.push((*aj)[j]);   //最先获取到的邻接顶点最后入栈,最先出栈  
  31.                 }  
  32.   
  33.                 r.add(v);  
  34.   
  35.                 visited[v] = true;  
  36.             }  
  37.         }  
  38.   
  39.         ret = toArray(r);  
  40.     }  
  41.     else  
  42.     {  
  43.         THROW_EXCEPTION(NoEnoughMemoryException,“Index i is invalid …”);  
  44.     }  
  45.   
  46.     return ret;  
  47. }  

main.cpp

  1. #include <iostream>  
  2. #include “MatrixGraph.h”  
  3.   
  4.   
  5. using namespace std;  
  6. using namespace DTLib;  
  7.   
  8. int main()  
  9. {  
  10.   
  11.     MatrixGraph<9,char,int> g;  
  12.   
  13.     const char* VD = “ABEDCGFHI”;  
  14.   
  15.     for(int i=0;i<9;i++)  
  16.     {  
  17.         g.setVertex(i,VD[i]);  
  18.     }  
  19.   
  20.     g.setEdge(0,1,0);  
  21.     g.setEdge(1,0,0);   //有向图表示无向图,权值0代表无权值  
  22.   
  23.     g.setEdge(0,3,0);  
  24.     g.setEdge(3,0,0);  
  25.   
  26.     g.setEdge(0,4,0);  
  27.     g.setEdge(4,0,0);  
  28.   
  29.     g.setEdge(1,2,0);  
  30.     g.setEdge(2,1,0);  
  31.   
  32.   
  33.     g.setEdge(1,4,0);  
  34.     g.setEdge(4,1,0);  
  35.   
  36.     g.setEdge(2,5,0);  
  37.     g.setEdge(5,2,0);  
  38.   
  39.     g.setEdge(3,6,0);  
  40.     g.setEdge(6,3,0);  
  41.   
  42.     g.setEdge(4,6,0);  
  43.     g.setEdge(6,4,0);  
  44.   
  45.     g.setEdge(6,7,0);  
  46.     g.setEdge(7,6,0);  
  47.   
  48.     g.setEdge(7,8,0);  
  49.     g.setEdge(8,7,0);  
  50.   
  51.     SharedPointer< Array<int> > sa = g.DFS(0);  
  52.   
  53.   
  54.     for(int i=0;i<sa->length();i++)  
  55.     {  
  56.         cout << (*sa)[i] << ” “;  
  57.     }  
  58.   
  59.   
  60.   
  61.   
  62.     return 0;  
  63. }  

                        《第75课 - 图的遍历(DFS)》

3、问题 

     
   如何使用二叉树先序遍历的思想遍历图? 

4、递归版深度优先

                《第75课 - 图的遍历(DFS)》

                               G = v0 + G’

                            DFS(G) = visited(v0) + DFS(G’)

                               G’不为空,且v0到G’有连接 


         – 定义功能: DFS(graph, vex

                   
 以顶点vex为起始顶点深度优先遍历graph 

        《第75课 - 图的遍历(DFS)》

5、编程实验 

递归版深度优先算法     DFS(graph, vex)

  1. #include <iostream>  
  2. #include “MatrixGraph.h”  
  3.   
  4.   
  5. using namespace std;  
  6. using namespace DTLib;  
  7.   
  8.   
  9. template < typename V, typename E >  
  10. void DFS(Graph<V, E>& g, int v, Array<bool>& visited)  
  11. {  
  12.     if((0 <= v)&&(v < g.vCount()))  
  13.     {  
  14.         cout<< v <<endl;  
  15.   
  16.         visited[v] = true;  
  17.   
  18.         SharedPointer< Array<int> > aj = g.getAdjacent(v);  
  19.   
  20.         for(int i=0;i<aj->length();i++) //v没有邻接顶点就不会递归调用  
  21.         {  
  22.             if( !visited[(*aj)[i]])  
  23.             {  
  24.                 DFS(g, (*aj)[i], visited);//从邻接顶点开始深度优先遍历子图  
  25.             }  
  26.         }  
  27.     }  
  28.     else  
  29.     {  
  30.         THROW_EXCEPTION(InvalidParameterException,“Index v is invalid …”);  
  31.     }  
  32. }  
  33.   
  34. template < typename V, typename E >  
  35. void DFS(Graph<V, E>& g, int v)  
  36. {  
  37.     DynamicArray<bool> visited(g.vCount());  
  38.   
  39.     for(int i=0;i<visited.length();i++)  
  40.     {  
  41.         visited[i] = false;  
  42.     }  
  43.   
  44.     DFS(g, v, visited);  
  45. }  
  46.   
  47.   
  48. int main()  
  49. {  
  50.   
  51.     MatrixGraph<9,char,int> g;  
  52.   
  53.     const char* VD = “ABEDCGFHI”;  
  54.   
  55.     for(int i=0;i<9;i++)  
  56.     {  
  57.         g.setVertex(i,VD[i]);  
  58.     }  
  59.   
  60.     g.setEdge(0,1,0);  
  61.     g.setEdge(1,0,0);   //有向图表示无向图,权值0代表无权值  
  62.   
  63.     g.setEdge(0,3,0);  
  64.     g.setEdge(3,0,0);  
  65.   
  66.     g.setEdge(0,4,0);  
  67.     g.setEdge(4,0,0);  
  68.   
  69.     g.setEdge(1,2,0);  
  70.     g.setEdge(2,1,0);  
  71.   
  72.   
  73.     g.setEdge(1,4,0);  
  74.     g.setEdge(4,1,0);  
  75.   
  76.     g.setEdge(2,5,0);  
  77.     g.setEdge(5,2,0);  
  78.   
  79.     g.setEdge(3,6,0);  
  80.     g.setEdge(6,3,0);  
  81.   
  82.     g.setEdge(4,6,0);  
  83.     g.setEdge(6,4,0);  
  84.   
  85.     g.setEdge(6,7,0);  
  86.     g.setEdge(7,6,0);  
  87.   
  88.     g.setEdge(7,8,0);  
  89.     g.setEdge(8,7,0);  
  90.   
  91.     SharedPointer< Array<int> > sa = g.DFS(0);  
  92.   
  93.   
  94.     for(int i=0;i<sa->length();i++)  
  95.     {  
  96.         cout << (*sa)[i] << ” “;  
  97.     }  
  98.   
  99.     DFS(g, 0);  
  100.   
  101.   
  102.     return 0;  
  103. }  

                            《第75课 - 图的遍历(DFS)》

6、小结 

            深度优先按照“先序遍历的方式”对顶点进行访问 

            深度优先算法的核心是栈的使用 

            深度优先和广度优先的唯一不同在于栈或队列的使用 

            深度优先算法可以使用递归的方式实现 

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