1. 程式人生 > >圖的兩種遍歷方式

圖的兩種遍歷方式

繼續 div input traversal 遍歷 n) logs i++ memset

圖的遍歷有兩種:深度優先和廣度優先。本文中,深度優先使用遞歸實現,每次遞歸找到第一個與當前結點相連且未輸出過的結點繼續往下遞歸,直至所有結點都已輸出。廣度優先將開始結點的所有鄰接結點全部壓入棧,當棧不為空時一直循環將棧首的結點的所有相鄰結點壓入棧。

具體代碼實現如下:

  1 //鄰接鏈表
  2 class Graph {
  3 private:
  4     //n: number of nodes
  5     int n;
  6     vector<int> *edges;
  7     bool *visited;
  8 public:
  9     Graph(int
input_n) { 10 n = input_n; 11 edges = new vector<int>[n]; 12 visited=new bool[n]; 13 //size of bool=1 14 memset(visited,0,n); 15 } 16 ~Graph() { 17 delete[] edges; 18 delete[] visited; 19 } 20 //no directions 21 void
insert(int x, int y) { 22 edges[x].push_back(y); 23 edges[y].push_back(x); 24 } 25 26 //visited will be changed after one traversal 27 //so need to reset for new operations 28 void reset_visited(){ 29 memset(visited,0,n); 30 } 31 32 void dfs(int
vertex) { 33 cout<<vertex<<endl; 34 visited[vertex]=true; 35 for(int adj_vertex: edges[vertex]){ 36 if(!visited[adj_vertex]){ 37 dfs(adj_vertex); 38 } 39 } 40 } 41 42 void bfs(int start_vertex) { 43 queue<int> bfs_queue; 44 bfs_queue.push(start_vertex); 45 visited[start_vertex]=true; 46 while(!bfs_queue.empty()){ 47 int vertex=bfs_queue.front(); 48 cout<<vertex<<endl; 49 bfs_queue.pop(); 50 for(int adj_vertex: edges[vertex]){ 51 //if it has not been put into the queue yet 52 if(!visited[adj_vertex]){ 53 visited[adj_vertex]=true; 54 bfs_queue.push(adj_vertex); 55 } 56 } 57 } 58 } 59 }; 60 61 62 63 64 //鄰接矩陣 65 class Graph { 66 private: 67 //指向鄰接矩陣 68 int **mat; 69 //n為頂點個數, 註意這裏頂點是從0開始編號的 70 int n; 71 bool *visited; 72 public: 73 Graph(int input_n) { 74 n = input_n; 75 mat = new int *[n]; 76 for (int i = 0; i < n; ++i) { 77 mat[i] = new int[n]; 78 memset(mat[i], 0, sizeof(int) * n); 79 } 80 visited=new bool[input_n]; 81 memset(visited,0,input_n); 82 } 83 ~Graph() { 84 for (int i = 0; i< n; ++i) { 85 delete[] mat[i]; 86 } 87 delete[] mat; 88 delete[] visited; 89 } 90 //flag=0為有向圖, flag=1為無向圖 91 void insert(int x,int y, int flag){ 92 mat[x][y]=1; 93 if(flag==1){ 94 mat[y][x]=1; 95 } 96 } 97 void output() { 98 for(int i=0;i<n;i++){ 99 for(int j=0;j<n;j++){ 100 cout<<mat[i][j]<<" "; 101 } 102 cout<<endl; 103 } 104 } 105 106 void reset_visited(){ 107 memset(visited,0,n); 108 } 109 110 void dfs(int cur_vertex){ 111 cout<<cur_vertex<<endl; 112 visited[cur_vertex]=true; 113 for(int adj_ver=0;adj_ver<n;adj_ver++){ 114 if((!visited[adj_ver]) && mat[cur_vertex][adj_ver]==1){ 115 dfs(adj_ver); 116 } 117 } 118 } 119 120 121 void bfs(int start_vertex){ 122 queue<int> bfs_queue; 123 bfs_queue.push(start_vertex); 124 visited[start_vertex]=true; 125 while(!bfs_queue.empty()){ 126 int cur_ver=bfs_queue.front(); 127 bfs_queue.pop(); 128 cout<<cur_ver<<endl; 129 for(int adj_ver=0; adj_ver<n; adj_ver++){ 130 if((!visited[adj_ver]) && mat[cur_ver][adj_ver]==1){ 131 bfs_queue.push(adj_ver); 132 visited[adj_ver]=true; 133 } 134 } 135 } 136 } 137 };

圖的兩種遍歷方式