#include <iostream> #include <vector> #include <stack> #define MaxSize 10 #define eletype int using namespace std; bool visited[MaxSize]; //全局数组,记录结点是否已补访问 int Degree[MaxSize]; //存储顶点的入度数 int time; //时间变量 int Time[MaxSize]; typedef struct edgenode { //边表结点 int adjvex; //邻接点 int weight; //权值 edgenode *next; //下一条边 }; typedef struct vertexnode { //顶点结点 eletype data; //结点数据 edgenode *fist; //指向第一条边 }AdjList[MaxSize]; typedef struct AdjListGraph { AdjList adjlist; //邻接表 int vex; //顶点数 int edge; //边数 }; void Init() { //初始化为未访问 for (int i = 0; i < MaxSize; i++) { visited[i] = false; Degree[i] = 0; } } int Location(AdjListGraph &G, eletype c) { //寻找顶点数据的邻接点 for (int i = 0; i < G.vex; i++) { if (G.adjlist[i].data == c) { return i; } } return -1; } void Create(AdjListGraph &G) { //创建图 cout << "请输入该图的顶点数以及边数:" << endl; cin >> G.vex >> G.edge; cout << "请输入相关顶点:" << endl; for (int i = 0; i < G.vex; i++) { cin >> G.adjlist[i].data; G.adjlist[i].fist = NULL; } eletype a, b; int c; int m, n; cout << "请输入相关边的顶点以及权值:" << endl; for (int i = 0; i < G.edge; i++) { cin >> a >> b>>c; m = Location(G, a); //寻找顶点号 n = Location(G, b); if (m != -1 && n != -1) { //寻找到位置 edgenode *temp = new edgenode; temp->adjvex = n; temp->weight = c; temp->next = G.adjlist[m].fist; G.adjlist[m].fist = temp; } } } void Obtaining_degree(AdjListGraph &G) { //求得每个顶点的入度 for (int i = 0; i < G.vex; i++) { edgenode *temp = G.adjlist[i].fist; if (temp != NULL) { Degree[temp->adjvex]++; while (temp->next != NULL) { temp = temp->next; Degree[temp->adjvex]++; } } } } void Topological_Sorting(AdjListGraph &G) { // 拓扑排序采用度的方法 cout << "第一种方法拓扑排序:"; stack<int> s; //初始化栈 for (int i = 0; i < G.vex; i++) { if (Degree[i] == 0) { s.push(i); } } int count = 0; //计数,记录当前已经输出的顶点数 while (!s.empty()) { //栈非空 int emp = s.top(); cout << G.adjlist[emp].data << " "; s.pop(); count++; //删除顶点以及相关边 edgenode *temp = G.adjlist[emp].fist; if (temp != NULL) { Degree[temp->adjvex]--; if (Degree[temp->adjvex] == 0) { s.push(temp->adjvex); } while (temp->next != NULL) { temp = temp->next; Degree[temp->adjvex]--; if (Degree[temp->adjvex] == 0) { s.push(temp->adjvex); } } } } if (count < G.vex) { cout << "存在环,失败!!!" << endl; } } void DFS(AdjListGraph &G, int v) { //图的深度遍历 int w; if (visited[v] == false) { visited[v] = true; //设置已访问过 } edgenode *temp = G.adjlist[v].fist; if (temp != NULL) { w = temp->adjvex; if (visited[w] == false) { DFS(G, w); } while (temp->next != NULL) { temp = temp->next; w = temp->adjvex; if (visited[w] == false) { DFS(G, w); } } } time = time + 1; Time[v] = time; //设置时间戳 } void DFS_Main(AdjListGraph &G) { //这个函数的存在是防止不连通图的存在 time = 0; for (int i = 0; i < G.vex; i++) { if (visited[i] == false) { DFS(G, i); } } } void Topological_Sorting1(AdjListGraph &G) { //这里我们就采用暴力排序的方法,简单粗暴 cout << "第二种方法拓扑排序:"; vector<bool> c; c.assign(G.vex, false); for (int i = 0; i < G.vex; i++) { int temp = 0, max = -1; for (int j = 0; j < G.vex; j++) { if (c[j]==false && max < Time[j]) { max = Time[j]; temp = j; } } //寻找最大值 c[temp] = true; cout << G.adjlist[temp].data << " "; } } int main() { AdjListGraph G; Init(); Create(G); //创建图 Obtaining_degree(G); Topological_Sorting(G); DFS_Main(G); Topological_Sorting1(G); system("pause"); return 0; } /* 5 7 1 2 3 4 5 1 4 0 1 2 0 2 4 0 4 3 0 3 5 0 4 5 0 2 3 0 */
文章来源: 图的两种拓扑排序