对一个有向无环图进行拓扑排序,过程如下:
- 从有向图中选择一个没有前驱(即入度为0)的顶点,压入栈中
- 删除栈中的顶点,同时删除该顶点出发的所有边(即顶点相邻边的顶点入度减一)
- 重复以上两步,直至栈为空
- 检查是否已经遍历图中所有结点,若全部遍历完成,则完成拓扑排序,反之,则该图存在环,拓扑排序失败。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define MaxSize 5
#define INF 99999
typedef struct ArcNode{
struct ArcNode* next;
int n;
}ArcNode;
typedef struct{
ArcNode* fristNode;
int in;
int data;
}VNode;
typedef struct{
int top;
VNode data[MaxSize];
}Stack;
typedef struct{
VNode arcList[MaxSize];
int n;
int e;
}AGraph;
void initAgraph(AGraph* &agraph){
ArcNode* e;
agraph->n =4;
agraph->e = 4;
for (int i = 0; i < agraph->n; i++) {
agraph->arcList[i].data = i;
agraph->arcList[i].fristNode = NULL; //置边表为空
}
e = new ArcNode();
e->n = 1;
e->next = agraph->arcList[0].fristNode;
agraph->arcList[0].fristNode = e;
e = new ArcNode();
e->n = 2;
e->next = agraph->arcList[0].fristNode;
agraph->arcList[0].fristNode = e;
e = new ArcNode();
e->n = 1;
e->next = agraph->arcList[3].fristNode;
agraph->arcList[3].fristNode = e;
e = new ArcNode();
e->n = 2;
e->next = agraph->arcList[3].fristNode;
agraph->arcList[3].fristNode = e;
}
void TopSort(AGraph* G){
Stack stack;
stack.top = -1;
int num = 0;
ArcNode* node;
//初始化
for (int i = 0; i < G->n; i++) {
node = G->arcList[i].fristNode;
while (node) {
(G->arcList[node->n].in)++;
node = node->next;
}
}
//寻找入度为0,并入栈
for (int i = 0; i < G->n; i++) {
if (G->arcList[i].in == 0) {
stack.top++;
stack.data[stack.top] = G->arcList[i];
}
}
//遍历
while (stack.top != -1) {
VNode q = stack.data[stack.top];
stack.top--;
num++;
cout<<num<<endl;
ArcNode* node = q.fristNode;
while (node) {
(G->arcList[node->n].in)--;
cout<<"kkk:"<<G->arcList[node->n].in<<endl;
if (G->arcList[node->n].in == 0) {
stack.top++;
stack.data[stack.top] = G->arcList[node->n];
}
node = node->next;
}
for (int i = 0; i < G->n; i++) {
cout<<"n:"<<G->arcList[i].in<<endl;
}
}
if (num == G->n) {
cout<<"Good"<<endl;
}else{
cout<<"fail"<<endl;
}
}
int main(int argc, const char * argv[]) {
AGraph* G = new AGraph();
initAgraph(G);
TopSort(G);
return 0;
}