IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构/C语言版】【图】拓扑排序 -> 正文阅读

[数据结构与算法]【数据结构/C语言版】【图】拓扑排序

拓扑排序

拓扑排序是对图结点关系进行的排序,其排序结果提供了一种无后效性的遍历图的方式,即:后续结点不会影响之前的结点。此性质可用于动态规划、关键路径等。
进行拓扑排序需要注意:1、需要了解图的度(入度与出度) 2、只有有向无环图才有拓扑序列。

入度出度

入度:当前结点入边的条数。
求入度时只需要遍历图,将所有出边的目标点入度indegree[v]++;

Status FindInDegree(ALGraph G, int* indegree)//求入度
{
	for (int i = 0; i < G.vexnum; i++) {
		ArcNode* p = G.vertices[i].firstarc->nextarc;
		while (p != NULL) {
			indegree[p->adjvex]++;
			p = p->nextarc;
		}
	}
	return 1;
}

出度:当前结点出边的条数。
结点的度:入度+出度等于结点的度。
易发现,如果每一个结点的入边作为限制此结点的条件的话,入度为零的点表示没有结点是此结点的先决条件。另外,此结点入度为零时表示此结点可顺利完成,那么此结点所影响结点入度应该减一。如果有环,则自己的先决条件是自己矛盾。

排序过程

将入度为零的结点放入一种存储结构(栈或队列)中,每次从存储结构中取出一个结点,将其能够直达的所有结点入度减一,若此时入度为零将则其加入存储结构,如此反复直至存储结构为空。

#define SElemType int
typedef struct SNode {
	SElemType data;
	SNode* next;
}SNode, * LinkStack;

Status InitStack(LinkStack& S)
{
	S = (LinkStack)malloc(sizeof(SNode));
	if (!S)
		return 0;
	S->next = NULL;
}

Status DestroyStack(LinkStack& S)
{
	LinkStack p = S->next, ptmp;
	while (p) {
		ptmp = p->next;
		free(p);
		p = ptmp;
	}
	free(S);
	return 1;
}

Status ClearStack(LinkStack& S)
{
	LinkStack p = S->next, ptmp;
	while (p) {
		ptmp = p->next;
		free(p);
		p = ptmp;
	}
	S->next = NULL;
	return 1;
}

Status StackEmpty(LinkStack& S)
{
	return S->next == NULL;
}

int StackLength(LinkStack S)
{
	int ans = 0;
	LinkStack p = S->next;
	while (p) {
		ans++;
		p = p->next;
	}
	return ans;
}

Status GetTop(LinkStack S, SElemType& e)
{
	if (S->next == NULL)
		return 0;
	e = S->next->data;
	return 1;
}

Status Push(LinkStack& S, SElemType e)
{
	SNode* p = (SNode*)malloc(sizeof(SNode));
	p->data = e;
	p->next = S->next;
	S->next = p;
	return 1;
}

Status Pop(LinkStack& S, SElemType& e)
{
	if (S->next == NULL)
		return 0;
	e = S->next->data;
	SNode* p = S->next;
	S->next = p->next;
	free(p);
	return 1;
}

Status visit(SElemType e)
{
	cout << e << endl;
	return 1;
}

基于邻接表

测试数据:

0
6 8
v1 v2 v3 v4 v5 v6
v1 v3
v1 v2
v2 v4
v2 v5
v5 v6
v4 v6
v3 v4
v3 v6

测试输出:

0 v1
2 v3
1 v2
3 v4
4 v5
5 v6

代码:

//求入度 
Status FindInDegree(ALGraph G, int* indegree)
{
	for (int i = 0; i < G.vexnum; i++) {
		ArcNode* p = G.vertices[i].firstarc->nextarc;
		while (p != NULL) {
			indegree[p->adjvex]++;
			p = p->nextarc;
		}
	}
	return 1;
}

//拓扑排序 
Status TopologicalOrder(ALGraph G)
{
	int indegree[MAX_VERTEX_NUM] = { 0 };
	FindInDegree(G, indegree);//求入度
	LinkStack S;
	InitStack(S);
	int i, count = 0;
	for(i=0;i<G.vexnum;i++){
		if (!indegree[i])
			Push(S, i);
	}
	while (!StackEmpty(S))
	{
		Pop(S, i);
		cout << i << ' ' << G.vertices[i].data << endl;
		count++;
		ArcNode* p = G.vertices[i].firstarc->nextarc;
		while (p != NULL) {
			int v = p->adjvex;
			if (!(--indegree[v])) Push(S, v);
			p = p->nextarc;
		}
	}
	if (count < G.vexnum)
		return ERROR;
	return 1;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:52:09  更:2021-11-30 15:53:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:55:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码