第七十四课 图的遍历(BFS)

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七十四课 图的遍历(BFS)相关的知识,希望对你有一定的参考价值。

技术分享图片

 

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

广度优先相当于对顶点进行分层,层次遍历。

技术分享图片

 

 技术分享图片

 

技术分享图片

 

 

 在Graph.h中添加BFS函数:

  1 #ifndef GRAPH_H
  2 #define GRAPH_H
  3 
  4 #include "Object.h"
  5 #include "SharedPointer.h"
  6 #include "Array.h"
  7 #include "DynamicArray.h"
  8 #include "LinkQueue.h"
  9 
 10 namespace DTLib
 11 {
 12 
 13 template < typename E >
 14 struct Edge : public Object
 15 {
 16     int b;
 17     int e;
 18     E data;
 19 
 20     Edge(int i=-1, int j=-1)
 21     {
 22         b = i;
 23         e = j;
 24     }
 25 
 26     Edge(int i, int j, const E& value)
 27     {
 28         b = i;
 29         e = j;
 30         data = value;
 31     }
 32 
 33     bool operator == (const Edge<E>& obj)
 34     {
 35         return (b == obj.b) && (e == obj.e);  //在这里不关注权值大小
 36     }
 37 
 38     bool operator != (const Edge<E>& obj)
 39     {
 40         return !(*this == obj);
 41     }
 42 };
 43 
 44 template < typename V, typename E >
 45 class Graph : public Object
 46 {
 47 protected:
 48     template < typename T >
 49     DynamicArray<T>* toArray(LinkQueue<T>& queue)
 50     {
 51         DynamicArray<T>* ret = new DynamicArray<T>(queue.length());
 52 
 53         if( ret != NULL )
 54         {
 55             for(int i=0; i<ret->length(); i++, queue.remove())
 56             {
 57                 ret->set(i, queue.front());
 58             }
 59         }
 60         else
 61         {
 62             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create ret object...");
 63         }
 64 
 65         return ret;
 66     }
 67 public:
 68     virtual V getVertex(int i) = 0;
 69     virtual bool getVertex(int i, V& value) = 0;
 70     virtual bool setVertex(int i, const V& value) = 0;
 71     virtual SharedPointer< Array<int> > getAdjacent(int i) = 0;
 72     virtual E getEdge(int i, int j) = 0;
 73     virtual bool getEdge(int i, int j, E& value) = 0;
 74     virtual bool setEdge(int i, int j, const E& value) = 0;
 75     virtual bool removeEdge(int i, int j) = 0;
 76     virtual int vCount() = 0;
 77     virtual int eCount() = 0;
 78     virtual int OD(int i) = 0;
 79     virtual int ID(int i) = 0;
 80     virtual int TD(int i)
 81     {
 82         return ID(i) + OD(i);
 83     }
 84 
 85     SharedPointer< Array<int> > BFS(int i)
 86     {
 87         DynamicArray<int>* ret = NULL;
 88 
 89         if( (0 <= i) && (i < vCount()) )
 90         {
 91             LinkQueue<int> q;
 92             LinkQueue<int> r;
 93             DynamicArray<bool> visited(vCount());
 94 
 95             for(int i=0; i<visited.length(); i++)
 96             {
 97                 visited[i] = false;
 98             }
 99 
100             q.add(i);
101 
102             while( q.length() > 0 )
103             {
104                 int v = q.front();
105 
106                 q.remove();
107 
108                 if( !visited[v] )
109                 {
110                     SharedPointer< Array<int> > aj = getAdjacent(v);
111 
112                     for(int j=0; j<aj->length(); j++)
113                     {
114                         q.add((*aj)[j]);
115                     }
116 
117                     r.add(v);
118 
119                     visited[v] = true;
120                 }
121             }
122 
123             ret = toArray(r);
124         }
125         else
126         {
127             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
128         }
129 
130         return ret;
131     }
132 };
133 
134 }
135 
136 #endif // GRAPH_H

 

测试程序如下:

 1 #include <iostream>
 2 #include "BTreeNode.h"
 3 #include "ListGraph.h"
 4 #include "MatrixGraph.h"
 5 
 6 using namespace std;
 7 using namespace DTLib;
 8 
 9 
10 int main()
11 {
12     MatrixGraph<9, char, int> g;
13     const char* VD = "ABEDCGFHI";
14 
15     for(int i=0; i<9; i++)
16     {
17         g.setVertex(0, VD[i]);
18     }
19 
20     g.setEdge(0, 1, 0);
21     g.setEdge(1, 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     g.setEdge(1, 4, 0);
33     g.setEdge(4, 1, 0);
34 
35     g.setEdge(2, 5, 0);
36     g.setEdge(5, 2, 0);
37 
38     g.setEdge(3, 6, 0);
39     g.setEdge(6, 3, 0);
40 
41     g.setEdge(4, 6, 0);
42     g.setEdge(6, 4, 0);
43 
44     g.setEdge(6, 7, 0);
45     g.setEdge(7, 6, 0);
46 
47     g.setEdge(7, 8, 0);
48     g.setEdge(8, 7, 0);
49 
50     SharedPointer< Array<int> > sa = g.BFS(0);
51 
52     for(int i=0; i<sa->length(); i++)
53     {
54         cout << (*sa)[i] << " ";
55     }
56 
57     cout << endl;
58 
59     return 0;
60 }

 广度优先的本质就是层次遍历。

结果如下:

技术分享图片

 

 

小结:

技术分享图片

 

以上是关于第七十四课 图的遍历(BFS)的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 第七十四期 - Android 新浪大图预览

第七十二课 图的存储结构(上)

第七十三课 图的存储结构(下)

第二十四课 单链表的遍历与优化

郑州-第七十四期前后端分离(SPA)与不分离(JSP) 工作流程分别是怎样的?

图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码进阶版