#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
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/coolsunxu/article/details/80668367
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。