图的两种拓扑排序

匿名 (未验证) 提交于 2019-12-03 00:26:01
#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  */  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!