第七章 图(邻接矩阵和邻接表建立图并实现DFS、BFS)
2017-12-07 22:30
363 查看
邻接矩阵建立图并实现图的深度优先遍历和广度优先遍历
/* 邻接矩阵实现图的广搜和深搜 */ #include<iostream> #include<queue> #define inf 1000000 //假设的无穷大 #define vertex_max_num 100 //设的最大顶点数 using namespace std; typedef struct { int v[vertex_max_num];//顶点名称 int adj_matrix[vertex_max_num][vertex_max_num];//邻接矩阵 int v_num, arc_num;//顶点数,弧数 int kind;//图的种类,0有向图,1有向网,2无向图,3无向网 }graph; int vis[vertex_max_num+1];//标志数组 //标志数组初始化 void init() { memset(vis, 0, sizeof(vis)); } //创建有向图 void dir_graph_create(graph &G) { cout << "请输入要创建的有向图的顶点数和弧数:"; cin >> G.v_num >> G.arc_num; //结点初始化 for (int i = 1; i <= G.v_num; i++) G.v[i] = i;//对结点编号 for (int i = 1; i <= G.v_num; i++) for (int j = 1; j <= G.v_num; j++) G.adj_matrix[i][j] = 0; cout << "请依次输入邻接可达的成对结点:" << endl; for (int i = 1; i <= G.arc_num; i++) { int v1, v2; cin >> v1 >> v2; G.adj_matrix[v1][v2] = 1; } } //创建有向网(带权有向图) void dir_net_create(graph &G) { cout << "请输入要创建的有向网的顶点数和弧数:"; cin >> G.v_num >> G.arc_num; //结点初始化 for (int i = 1; i <= G.v_num; i++) G.v[i] = i;//对结点编号 for (int i = 1; i <= G.v_num; i++) for (int j = 1; j <= G.v_num; j++) G.adj_matrix[i][j] = inf; cout << "请依次输入邻接可达的成对结点及弧长:" << endl; for (int i = 1; i <= G.arc_num; i++) { int v1, v2,w; cin >> v1 >> v2 >> w; G.adj_matrix[v1][v2] = w; } } //创建无向图 void udir_graph_create(graph &G) { cout << "请输入要创建的无向图的顶点数和弧数:"; cin >> G.v_num >> G.arc_num; //结点初始化 for (int i = 1; i <= G.v_num; i++) G.v[i] = i;//对结点编号 for (int i = 1; i <= G.v_num; i++) for (int j = 1; j <= G.v_num; j++) G.adj_matrix[i][j] = 0; cout << "请依次输入邻接的成对结点:" << endl; for (int i = 1; i <= G.arc_num; i++) { int v1, v2; cin >> v1 >> v2; G.adj_matrix[v1][v2] = 1; G.adj_matrix[v2][v1] = 1; } } //创建无向网(带权无向图) void udir_net_create(graph &G) { cout << "请输入要创建的无向网的顶点数和弧数:"; cin >> G.v_num >> G.arc_num; //结点初始化 for (int i = 1; i <= G.v_num; i++) G.v[i] = i;//对结点编号 for (int i = 1; i <= G.v_num; i++) for (int j = 1; j <= G.v_num; j++) G.adj_matrix[i][j] = inf; cout << "请依次输入邻接的成对结点及弧长:" << endl; for (int i = 1; i <= G.arc_num; i++) { int v1, v2, w; cin >> v1 >> v2 >> w; G.adj_matrix[v1][v2] = w; G.adj_matrix[v2][v1] = w; } } void graph_create(graph &G) { cout << "************" << endl; cout << "0-----有向图" << endl; cout << "1-----有向网" << endl; cout << "2-----无向图" << endl; cout << "3-----无向网" << endl; cout << "************" << endl; cout << "根据上方菜单,输入相应数字,来创建你想要类型的图" << endl; cin >> G.kind; switch (G.kind) { case 0:dir_graph_create(G); break; case 1:dir_net_create(G); break; case 2:udir_graph_create(G); break; case 3:udir_net_create(G); break; default:return; } } //图深度优先遍历 void dfs1(graph G, int v) { if (!vis[v]) { cout << G.v[v]<<" "; vis[v] = 1; } for (int i = 1; i <= G.v_num; i++) if (!vis[i] && G.adj_matrix[v][i]==1) dfs1(G, i); } //网深度优先遍历 void dfs2(graph G, int v) { if (!vis[v]) { cout << G.v[v]<<" "; vis[v] = 1; } for (int i = 1; i <= G.v_num; i++) { if (!vis[i] && G.adj_matrix[v][i] != inf) dfs2(G, i); } } //深度优先遍历 void dfs(graph G, int v) { init(); cout << "深度优先遍历结果:"; switch (G.kind) { case 0: case 2:dfs1(G, v); break; case 1: case 3:dfs2(G, v); break; default:return; } cout << endl; } //广度优先遍历 void bfs(graph G, int v) { init(); cout << "广度优先遍历结果:"; queue<int>que; if (!vis[v]) { cout << G.v[v] << " "; vis[v] = 1; que.push(v); } while (!que.empty()) { int vertex = que.front(); que.pop(); for (int i = 1; i <= G.v_num; i++) { if (!vis[i]) { if (((G.kind == 0 || G.kind == 2) && G.adj_matrix[vertex][i] == 1) || ((G.kind==1 || G.kind==3) && G.adj_matrix[vertex][i]!=inf)) { cout << G.v[i] << " "; vis[i] = 1; que.push(i); } } } } cout << endl; } int main() { graph G; graph_create(G); dfs(G, 1); bfs(G, 1); return 0; } /* 下面样例以此图为例 1-3-4 | 6-2-5 |___| 下面输入输出样例已去除文字说明 输入样例 2 6 6 1 2 1 3 2 5 2 6 3 4 5 6 输出样例 1 2 5 6 3 4 1 2 3 5 6 4 */
邻接表建立图并实现图的深度优先遍历和广度优先遍历
/* 本程序用邻接表实现图的深搜和广搜 以无向网为例,本例子中的无向网如下(边权重没有写): A-B-C | F-D-E |___| //下面是基于上面无向网的输入输出样例(这里权重都简为1) 请输入要创建的图的结点数和边数:6 6 ======================================== 结点信息如下 第1个结点是A 第2个结点是B 第3个结点是C 第4个结点是D 第5个结点是E 第6个结点是F ======================================== 边信息如下 请输入第1条边相连的两个结点编号及边的权重:1 2 1 请输入第2条边相连的两个结点编号及边的权重:1 4 1 请输入第3条边相连的两个结点编号及边的权重:2 3 1 请输入第4条边相连的两个结点编号及边的权重:4 5 1 请输入第5条边相连的两个结点编号及边的权重:4 6 1 请输入第6条边相连的两个结点编号及边的权重:5 6 1 邻接表如下: A→B→D B→A→C C→B D→A→E→F E→D→F F→D→E 从各个结点出发深搜结果: A B C D E F B A D E F C C B A D E F D A B C E F E D A B C F F D A B C E 从各个结点出发广搜结果: A B D C E F B A C D E F C B A D E F D A E F B C E D F A B C F D E A B C */ #include<iostream> #include<queue> using namespace std; const int vertex_max = 100; typedef char vertex_type; //边 typedef struct edge_node { int vertex;//边所指向的结点编号 struct edge_node *next;//下一条边 }edge; //结点 typedef struct vertex_node { vertex_type e;//结点名字 edge *side; }vertex; typedef struct Graph { vertex adj_list[vertex_max+1];//邻接表 int w[vertex_max+1][vertex_max + 1];//边权重 int v_num, e_num;//结点数、边数 }graph; bool vis[vertex_max + 1]; void init() { memset(vis, 0, sizeof(vis)); } //建立图 void graph_create(graph &G) { cout << "请输入要创建的图的结点数和边数:"; cin >> G.v_num >> G.e_num; cout << "========================================" << endl; cout << "结点信息如下"<<endl; for (int i = 1; i <= G.v_num; i++) { cout << "第" << i << "个结点是"; cin >> G.adj_list[i].e; G.adj_list[i].side = nullptr; } cout << "========================================" << endl; cout << "边信息如下" << endl; for (int i = 1; i <= G.e_num; i++) { cout << "请输入第" << i << "条边相连的两个结点编号及边的权重:"; int x, y,weight; cin >> x >> y >> weight; G.w[x][y] = G.w[y][x] = weight; edge *p_edge = new edge; edge *q_edge = new edge; p_edge->next = nullptr; p_edge->vertex = y; q_edge->next = nullptr; q_edge->vertex = x; edge *tmp1 = G.adj_list[x].side; edge *tmp2 = G.adj_list[y].side; //把x结点指向y结点 while (tmp1) { if (tmp1->next == nullptr) break; tmp1 = tmp1->next; } if (tmp1 == nullptr) G.adj_list[x].side = p_edge; else tmp1->next = p_edge; //把y结点指向x结点 while (tmp2) { if (tmp2->next == nullptr) break; tmp2 = tmp2->next; } if (tmp2 == nullptr) G.adj_list[y].side = q_edge; else tmp2->next = q_edge; } } //打印邻接表 void adj_list_print(graph G) { for (int i = 1; i <= G.v_num; i++) { cout << G.adj_list[i].e; edge *tmp = G.adj_list[i].side; while (tmp) { cout <<"→"<< G.adj_list[tmp->vertex].e; tmp = tmp->next; } cout << endl; } } //深搜(从某结点出发搜索) void dfs1(graph G, int v) { if (!vis[v]) { cout << G.adj_list[v].e << " "; vis[v] = true; } edge *p = G.adj_list[v].side; while (p) { if (!vis[p->vertex]) dfs1(G, p->vertex); p = p->next; } } //深搜(从各个结点出发搜索) void dfs(graph G) { for (int i = 1; i <= G.v_num; i++) { init(); dfs1(G, i); cout << endl; } } //广搜(从某个结点出发搜索) void bfs1(graph G,int i) { init(); queue<int>que; if (!vis[i]) { cout << G.adj_list[i].e << " "; que.push(i); vis[i] = 1; } while (!que.empty()) { int ii = que.front(); que.pop(); edge *p = G.adj_list[ii].side; while (p) { if (!vis[p->vertex]) { cout << G.adj_list[p->vertex].e << " "; que.push(p->vertex); vis[p->vertex] = 1; } p = p->next; } } } //广搜(从各个结点出发搜索) void bfs(graph G) { for (int i = 1; i <= G.v_num; i++) { bfs1(G, i); cout << endl; } } int main() { graph G; graph_create(G); cout << "邻接表如下:" << endl; adj_list_print(G); cout << "从各个结点出发深搜结果:" << endl; dfs(G); cout << "从各个结点出发广搜结果:" << endl; bfs(G); return 0; }
相关文章推荐
- java版 图的邻接表、邻接矩阵、BFS、DFS 实现
- 基于邻接矩阵和邻接表的两种方法实现无向图的BFS和DFS
- 用邻接表存储有向图实现的dfs和bfs
- DFS BFS遍历图 邻接表实现
- C语言实现图的邻接矩阵和BFS DFS
- sdut 2141 BFS(用邻接矩阵和邻接表(采用优先队列)实现
- 数据结构 学习笔记(七):图(上):图的表示方法(邻接表,邻接矩阵),遍历(DFS,BFS)
- 第六章:图。(邻接表实现图的存储及dfs、bfs)
- 第六章:图。(邻接矩阵实现图的存储及dfs、bfs)
- 图的深度优先遍历DFS(分别以邻接矩阵和邻接表实现)
- java实现邻接表图、DFS、BFS
- 在邻接矩阵中的DFS与BFS的实现
- 数据结构 《2》----基于邻接表表示的图的实现 DFS(递归和非递归), BFS
- DFS和BFS 邻接矩阵和邻接表
- 第六章:图。(邻接表实现图的存储及dfs、bfs)
- 关于邻接表实现适用两种深搜(DFS)和广搜(BFS)的代码
- 数据结构之——用C++实现邻接表的DFS与BFS
- 邻接表和邻接矩阵手写简洁代码DFS BFS
- 数据结构 《2》----基于邻接表表示的图的实现 DFS(递归和非递归), BFS
- 邻接表和邻接矩阵手写简洁代码DFS BFS