图(有向图,无向图)的邻接矩阵表示C++实现(遍历,拓扑排序,最短路径,最小生成树) Implement of digraph and undigraph using adjacency matrix
来源:互联网 发布:linux安装源码包 编辑:程序博客网 时间:2024/05/17 17:56
本文实现了有向图,无向图的邻接矩阵表示,并且实现了从创建到销毁图的各种操作。
以及两种图的深度优先遍历,广度优先遍历,Dijkstra最短路径算法,Prim最小生成树算法,有向图的拓扑排序算法。
通过一个全局变量控制当前图为有向图还是无向图。
若为无向图,则生成的邻接矩阵是对称的,有向图则不对称。
可结合我的另一篇文章(图的邻接表表示)看。
PS: 等有时间了作详细的讲解。
#include <iostream>#include <climits>#include <sstream> #include <queue>using namespace std;const bool UNDIGRAPH = 0;struct Graph{string *vertexLabel;//the number of the labels is equal to vertexesint vertexes;int edges;int **AdjMat;bool *visited;//only for DFS,BFS,Dijkstraint *distance; //only for Dijkstraint *path;//only for Dijkstra};void BuildGraph(Graph *&graph, int n){if (graph == NULL){graph = new Graph;graph->vertexes = n;graph->edges = 0;graph->AdjMat = new int *[n];graph->vertexLabel = new string[n];graph->visited = new bool[n];graph->distance = new int[n];graph->path = new int[n];for (int i = 0; i < graph->vertexes; i++){stringstream ss; ss<<"v" << i+1; ss >> graph->vertexLabel[i];graph->visited[i] = false;graph->distance[i] = INT_MAX;graph->path[i] = -1;graph->AdjMat[i] = new int[n];if(UNDIGRAPH)memset(graph->AdjMat[i],0, n * sizeof(int));elsefor (int j = 0; j < graph->vertexes; j++){if(i == j)graph->AdjMat[i][j] = 0;elsegraph->AdjMat[i][j] = INT_MAX;}}}}void MakeEmpty(Graph *&graph){if(graph == NULL)return;delete []graph->vertexLabel;delete []graph->visited;delete []graph->distance;delete []graph->path;for (int i = 0; i < graph->vertexes; i++){delete []graph->AdjMat[i];}delete []graph->AdjMat;delete graph;}void AddEdge(Graph *graph,int v1, int v2, int weight){if (graph == NULL) return;if (v1 < 0 || v1 > graph->vertexes-1) return;if (v2 < 0 || v2 > graph->vertexes-1) return;if (v1 == v2) return; //no loop is allowedif(UNDIGRAPH){if (graph->AdjMat[v1][v2] == 0)//not exist,edges plus 1 graph->edges++;graph->AdjMat[v1][v2] = graph->AdjMat[v2][v1] = weight;}else{if (graph->AdjMat[v1][v2] == 0 || graph->AdjMat[v1][v2] == INT_MAX)//not exist,edges plus 1graph->edges++;graph->AdjMat[v1][v2] = weight;}}void RemoveEdge(Graph *graph, int v1, int v2){if (graph == NULL) return;if (v1 < 0 || v1 > graph->vertexes-1) return;if (v2 < 0 || v2 > graph->vertexes-1) return;if (v1 == v2) return; //no loop is allowedif (UNDIGRAPH){if (graph->AdjMat[v1][v2] == 0)//not exists,return return;graph->AdjMat[v1][v2] = graph->AdjMat[v2][v1] = 0; graph->edges--; }else{if (graph->AdjMat[v1][v2] == 0 || graph->AdjMat[v1][v2] == INT_MAX)//not exists,returnreturn;graph->AdjMat[v1][v2] = INT_MAX;graph->edges--;}}int GetIndegree(Graph *graph, int v){if(graph == NULL) return -1;if(v < 0 || v > graph->vertexes -1) return -2;if(UNDIGRAPH) return -3;int degree = 0;for (int i = 0; i < graph->vertexes; i++){if(graph->AdjMat[i][v] != 0 && graph->AdjMat[i][v] != INT_MAX)degree++;}return degree;}int GetOutdegree(Graph *graph, int v){if(graph == NULL) return -1;if(v < 0 || v > graph->vertexes -1) return -2;if(UNDIGRAPH) return -3;int degree = 0;for (int i = 0; i < graph->vertexes; i++){if(graph->AdjMat[v][i] != 0 && graph->AdjMat[v][i] != INT_MAX)degree++;}return degree;}int GetDegree(Graph *graph, int v){if(graph == NULL) return -1;if(v < 0 || v > graph->vertexes -1) return -2;if(UNDIGRAPH){int degree = 0; for (int i = 0; i < graph->vertexes; i++) { if(graph->AdjMat[v][i] != 0) degree++; } return degree; }elsereturn GetIndegree(graph,v) + GetOutdegree(graph,v);}void PrintGraph(Graph *graph){if(graph == NULL)return;cout << "Vertex: " << graph->vertexes <<"\n";cout << "Edge: " << graph->edges << "\n";for (int i = 0; i < graph->vertexes; i++){cout << " "<< graph->vertexLabel[i];}cout << "\n";for (int i = 0; i < graph->vertexes; i++){for (int j = 0; j < graph->vertexes; j++){if(j == 0)cout << graph->vertexLabel[i] << " ";if(graph->AdjMat[i][j] == INT_MAX)cout << "~" << " ";elsecout << graph->AdjMat[i][j] << " ";}cout << "\n";}cout << "\n";}//depth first search (use stack or recursion)//DFS is similar to preorder traversal of treesvoid DFS(Graph *graph, int i){if (!graph->visited[i]){cout << graph->vertexLabel[i] << " ";graph->visited[i] = true;}for (int j = 0; j < graph->vertexes; j++){if (UNDIGRAPH){if (graph->AdjMat[i][j] != 0 && !graph->visited[j])DFS(graph,j);}else{if (graph->AdjMat[i][j] != INT_MAX && !graph->visited[j])DFS(graph,j);}}}void BeginDFS(Graph *graph){if(graph == NULL) return;cout << "DFS\n";for (int i = 0; i < graph->vertexes; i++)graph->visited[i] = false;for (int i = 0; i < graph->vertexes; i++)DFS(graph,i);}//breadth first search(use queue)//BFS is similar to leverorder traversal of trees//all of the vertexes will be searched once no matter how the digraph is constructedvoid BFS(Graph *graph){if(graph == NULL)return;cout << "BFS\n";memset(graph->visited,false,graph->vertexes * sizeof(bool));queue<int> QVertex;for (int i = 0; i < graph->vertexes; i++){if (!graph->visited[i]){QVertex.push(i);cout << graph->vertexLabel[i] << " ";graph->visited[i] = true;while(!QVertex.empty()){int vtxNO = QVertex.front();QVertex.pop();for (int j = 0; j < graph->vertexes; j++){if (UNDIGRAPH){if(!graph->visited[j] && graph->AdjMat[vtxNO][j]!=0){cout << graph->vertexLabel[j] << " ";graph->visited[j] = true;QVertex.push(j);}}else{if(!graph->visited[j] && graph->AdjMat[vtxNO][j]!=INT_MAX){cout << graph->vertexLabel[j] << " ";graph->visited[j] = true;QVertex.push(j);}}}}}}cout << "\n";}//after executing this function,the value of AdjMat changedvoid TopologicalSort(Graph *graph){if(UNDIGRAPH) return;if(graph == NULL) return;cout << "TopologicalSort"<<"\n";int counter = 0;queue <int> qVertex;for (int i = 0; i < graph->vertexes; i++){if(GetIndegree(graph,i) == 0)qVertex.push(i);}while (!qVertex.empty()){int vertexNO = qVertex.front();counter++;cout << graph->vertexLabel[vertexNO];if(counter != graph->vertexes)cout << " > ";qVertex.pop();for (int i = 0; i < graph->vertexes; i++){if(i == vertexNO) continue;if (GetIndegree(graph,i) != 0){graph->AdjMat[vertexNO][i] = INT_MAX;//indegree--if(GetIndegree(graph,i) == 0)qVertex.push(i);}}}cout << "\n";}void Dijkstra(Graph *graph, int v){if(graph == NULL) return;if(v < 0 || v > graph->vertexes-1) return;for (int i = 0; i < graph->vertexes; i++){graph->visited[i] = false;graph->distance[i] = INT_MAX;//can delete this line,as initialized in BuildGraphgraph->path[i] = -1;}graph->distance[v] = 0;//the rest are all INT_MAXwhile(1){int minDisInx = -1;int minDis = INT_MAX;for (int i = 0; i < graph->vertexes; i++){if(!graph->visited[i]){if(graph->distance[i] < minDis){minDis = graph->distance[i];minDisInx = i;}}}if(minDisInx == -1)//all visitedbreak;graph->visited[minDisInx] = true;for (int i = 0; i < graph->vertexes; i++){//unvisited and adjacent to current vertex//&& graph->AdjMat[minDisInx][i]!=0 is for undigraphif (!graph->visited[i] && graph->AdjMat[minDisInx][i]!=INT_MAX && graph->AdjMat[minDisInx][i]!=0){if (graph->distance[minDisInx] + graph->AdjMat[minDisInx][i] < graph->distance[i]){graph->distance[i] = graph->distance[minDisInx] + graph->AdjMat[minDisInx][i];graph->path[i] = minDisInx;cout << graph->vertexLabel[i] << " Updated to " << graph->distance[i] <<"\n";}}}}cout << "Vertex Visited Distance Path\n";for (int i = 0; i < graph->vertexes; i++){cout << graph->vertexLabel[i]<< "";cout << graph->visited[i]<< "";cout << graph->distance[i]<< "";if(graph->path[i] == -1)cout << "NONE\n";elsecout << graph->vertexLabel[graph->path[i]]<< "\n";}}//almost for undigraphvoid Prim(Graph *graph, int v){if(graph == NULL) return;if(v < 0 || v > graph->vertexes-1) return;for (int i = 0; i < graph->vertexes; i++){graph->visited[i] = false;graph->distance[i] = INT_MAX;//can delete this line,as initialized in BuildGraphgraph->path[i] = -1;}graph->distance[v] = 0;//the rest are all INT_MAXwhile(1){int minDisInx = -1;int minDis = INT_MAX;for (int i = 0; i < graph->vertexes; i++){if(!graph->visited[i]){if(graph->distance[i] < minDis){minDis = graph->distance[i];minDisInx = i;}}}if(minDisInx == -1)//all visitedbreak;graph->visited[minDisInx] = true;for (int i = 0; i < graph->vertexes; i++){//unvisited and adjacent to current vertex//&& graph->AdjMat[minDisInx][i]!=0 is for undigraphif (!graph->visited[i] && graph->AdjMat[minDisInx][i]!=INT_MAX && graph->AdjMat[minDisInx][i]!=0){if (graph->AdjMat[minDisInx][i] < graph->distance[i]){graph->distance[i] = graph->AdjMat[minDisInx][i];graph->path[i] = minDisInx;cout << graph->vertexLabel[i] << " Updated to " << graph->distance[i] <<"\n";}}}}cout << "Vertex Visited Distance Path\n";for (int i = 0; i < graph->vertexes; i++){cout << graph->vertexLabel[i]<< "";cout << graph->visited[i]<< "";cout << graph->distance[i]<< "";if(graph->path[i] == -1)cout << "NONE\n";elsecout << graph->vertexLabel[graph->path[i]]<< "\n";}}int main(){Graph *graph = NULL;BuildGraph(graph,7);PrintGraph(graph);//for simple test, 0 indexed/*AddEdge(graph,0,1,1);AddEdge(graph,0,2,1);AddEdge(graph,1,3,1);*///for TopologicalSort//0 indexed/*AddEdge(graph,0,1,1);AddEdge(graph,0,2,1);AddEdge(graph,0,3,1);AddEdge(graph,1,3,1);AddEdge(graph,1,4,1);AddEdge(graph,2,5,1);AddEdge(graph,3,2,1);AddEdge(graph,3,5,1);AddEdge(graph,3,6,1);AddEdge(graph,4,3,1);AddEdge(graph,4,6,1);AddEdge(graph,6,5,1);*///for Dijkstra(shortest path),Prim(minimum spanning tree)//0 indexedAddEdge(graph,0,1,2); AddEdge(graph,0,3,1); AddEdge(graph,1,3,3); AddEdge(graph,1,4,10); AddEdge(graph,2,0,4); AddEdge(graph,2,5,5); AddEdge(graph,3,2,2);AddEdge(graph,3,4,2);AddEdge(graph,3,5,8); AddEdge(graph,3,6,4); AddEdge(graph,4,6,6); AddEdge(graph,6,5,1);PrintGraph(graph);BeginDFS(graph);cout << "\n";BFS(graph);for (int i = 0; i < graph->vertexes; i++){cout << "\n";Dijkstra(graph,i);}Prim(graph,0);TopologicalSort(graph);MakeEmpty(graph);return 0;}
0 0
- 图(有向图,无向图)的邻接矩阵表示C++实现(遍历,拓扑排序,最短路径,最小生成树) Implement of digraph and undigraph using adjacency matrix
- 图(有向图)的邻接表表示 C++实现(遍历,拓扑排序,最短路径,最小生成树) Implement of digraph and undigraph using adjacency list
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径
- 图的实现、无向图的最小生成树、有向图的最短路径
- 无向图(Undigraph)
- 数据结构:图的存储、图的遍历、最小生成树、最短路径、拓扑排序
- Java实现图:邻接矩阵表示、深度优先搜索、广度优先搜索、无向图的最小生成树
- 无向图最小生成树、次小生成树、最短路径模版
- Adjacency Matrix of Graph(图的邻接矩阵)
- 无向图的邻接矩阵表示和遍历
- 拓扑排序+最短路径(无环加权有向图最短路径算法)
- 无向图的最短路径算法(队列实现 )
- 邻接矩阵(有向图,无向图实现的差异)
- 有向图转换&遍历&拓扑&最短路径
- 无向图有向图邻接矩阵表示法
- 有向图的最短路径
- 欧盟放弃对中国电信产品反倾销调查
- 中兴华为继续应诉欧盟无线网卡反倾销
- 第一课、Cocos2d-x 环境搭载
- 勇气
- 友元
- 图(有向图,无向图)的邻接矩阵表示C++实现(遍历,拓扑排序,最短路径,最小生成树) Implement of digraph and undigraph using adjacency matrix
- JSON 语法学习资料
- POJ-1422 Air Raid 最小路径覆盖模板题
- STL之set集合容器
- 中概股连续两日遭血洗:酷6优土跌幅均超6%
- android常用权限
- 中概股周四遭“血洗”:去哪儿大跌11.6%
- 嵌入式C面试题
- 周一中概股多数随大盘上涨 太阳能表现依旧低迷