图的两种遍历方式
Posted NoviScl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的两种遍历方式相关的知识,希望对你有一定的参考价值。
图的遍历有两种:深度优先和广度优先。本文中,深度优先使用递归实现,每次递归找到第一个与当前结点相连且未输出过的结点继续往下递归,直至所有结点都已输出。广度优先将开始结点的所有邻接结点全部压入栈,当栈不为空时一直循环将栈首的结点的所有相邻结点压入栈。
具体代码实现如下:
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 };
以上是关于图的两种遍历方式的主要内容,如果未能解决你的问题,请参考以下文章