事件的发生有先后顺序
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
#define MaxVertexNum 100 // 图中顶点数目的最大值
typedef int VertexType;
// 需要设计两种结点结构类型:一是顶点表的顶点,二是单链表的结点
typedef struct ArcNode{ // 边表结点
int adjvex; // 该弧所指向的顶点的位置
struct ArcNode *next; // 指向下一条弧的指针
};
typedef struct VNode{ // 顶点表结点
VertexType data; // 顶点信息
ArcNode * firstedge; // 单链表头指针
}VNode,AdjList[MaxVertexNum];
typedef struct{
AdjList vertices; // 顶点表
int vexnum, arcnum; // 图的顶点数和弧数
}ALGraph;
typedef struct Stack{
int top;
int data[MaxVertexNum];
};
void InitStack(Stack * s){
s->top = -1;
}
void Push(Stack *s, int i){
if (s->top + 1 == MaxVertexNum) return;
s->data[++s->top] = i;
}
void Pop(Stack *s, int &i){
if (s->top == -1) return;
i = s->data[s->top];
--s->top;
}
bool IsEmpty(Stack *s){
if (s->top == -1) return true;
return false;
}
int indegree[MaxVertexNum]; // 入度数组
void CreateAL(ALGraph *g){
int end;
int start;
cout << "请输入结点数和边数:";
cin >> g->vexnum >> g->arcnum;
cout << "请输入每个顶点保存的数据:" << endl;
for (int i = 0; i < g->vexnum; ++i){
cout << "vertex " << i << ":";
cin >> g->vertices[i].data; // 给每一个顶点赋值
g->vertices[i].firstedge = NULL; // 初始化时一定要让每个顶点的指针为空,否则为野指针
}
cout << "请输入每条边的两个顶点在数组中的下标(中间用空格分隔)" << endl;
for (int i = 0; i < g->arcnum; ++i){
indegree[i] = 0;
}
for (int j = 0; j < g->arcnum; ++j){ // 初始化弧
cout << "请输入第" << j << "条边" << endl;
cin >> start >> end; // 接收从start -----> end
ArcNode *node = new ArcNode;
node->adjvex = end; // 该弧所指向的顶点的位置(弧头)
indegree[end]++; // 该弧头顶点的入度+1
node->next = g->vertices[start].firstedge; // 头插法插入边结点
g->vertices[start].firstedge = node; // 顶点的firstedef为node
}
}
bool TopologicalSort(ALGraph g){
Stack * s = new Stack;
int v;
InitStack(s); // 初始化栈,存储入度为0的顶点为0的顶点
for (int i = 0; i < g.vexnum; ++i){
if (indegree[i] == 0) // 将所有入度为0的顶点进栈
Push(s, i);
}
int count = 0; // 计数,记录当前已经输出的顶点数
int out ; // 接收栈顶结点的下标
while (!IsEmpty(s)){ // 栈不空,则存在入度为0的顶点
Pop(s, out);
count++;
cout << g.vertices[out].data; // 打印结点的值
for (ArcNode *p = g.vertices[out].firstedge; p; p = p->next){ // 删除入度为0结点的所有边,然后
v = p->adjvex; // 取这条弧指向的顶点 // 更新入度表
if (!(--indegree[v])) Push(s, v); // 入度减1为0,则入站
}
}
if (count < g.vexnum) return false; // 排序失败,有向图中有回路
else return true; // 拓扑排序成功
}
int main(void) {
ALGraph* g = (ALGraph*)malloc(sizeof(ALGraph));//创建邻接表
CreateAL(g);//屏幕打印邻接表
bool a = TopologicalSort(*g);
cout << endl;
if (a){
cout << "排序成功" << endl;
}
else{
cout << "排序失败" << endl;
}
system("pause");
return 0;
}