图的两种拓扑排序

#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

*/

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/coolsunxu/article/details/80668367
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞