拓扑排序

事件的发生有先后顺序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#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;
}

在这里插入图片描述

拓扑排序不唯一,顺序根据你邻接表的边的顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值