AOV网络与拓扑(二)——实现

该博客介绍了如何对有向图进行拓扑排序,并在C++中实现这一过程。通过示例输入和输出展示了拓扑排序的结果,同时在存在有向环的情况下,程序能检测到并给出提示。文章提供了具体的代码实现。
摘要由CSDN通过智能技术生成

例:对于输入的有向图进行拓扑排序,并输出一个拓扑有序序列;如果存在有向环,则给出提示信息。

首先输入顶点个数n和边数m;然后输入每条边<u,v>,输入0 0结束;顶点序号从1开始记起。

样例输入:

6 8

1 2

1 4

2 6

3 2

3 6

5 1

5 2

5 6

6 8

1 3

1 2

2 5

3 4

4 2

4 6

5 4

5 6

0 0

样例输出:

5 1 4 3 2 6

Network has a cycle!

分析:

样例中第一组测试数据描述的有向图:


样例中第二组测试数据描述的有向图:

存在有向回路的AOV网络。

下面奉上具体实现~

Code:

#include<iostream>
using namespace std;

#define MAX 10			//顶点个数的最大值

struct ArcNode
{
	int to;
	struct ArcNode *next;
};

int n, m;				//顶点个数、边数
ArcNode *List[MAX];		//每个顶点的边链表表头指针
int count[MAX];			//各顶点的入度
char output[100];		//输出内容

void TopSort()
{
	int i, top = -1;
	ArcNode *temp;
	bool bcycle = false;	//是否存在有向环的标志
	int pos = 0;			//写入output数组的位置
	for(i = 0; i < n; i++)	//入度为0的顶点入栈
	{
		if(count[i] == 0) 
		{
			count[i] = top; 
			top = i;
		}
	}
	for(i = 0; i < n; i++)
	{
		if(top == -1)		//栈为空,存在有向回路
		{
			bcycle = true;
			break;
		}
		else
		{
			int j = top; top = count[top];		//栈顶顶点j出栈
			pos += sprintf(output+pos, "%d ", j+1);
			temp = List[j];
			//遍历顶点j的边链表,每条出边的终点的入度减1
			while(temp != NULL)
			{
				int k = temp->to;
				if(--count[k] == 0)
				{
					count[k] = top;
					top = k;
				}
				temp = temp->next;
			}
		}
	}
	if(bcycle) printf("Network has a cycle!\n");
	else
	{
		output[pos-1] = '\n';	//去掉最后的空格
		printf(output);
	}
}
int main()
{
	int i, u, v;		//循环变量、边的起点和终点
	while(1)
	{
		scanf("%d%d", &n, &m);	//读入顶点个数、边数
		if(n == 0 && m == 0) break;
		memset(List, 0, sizeof(List));
		memset(count, 0, sizeof(count));
		memset(output, 0, sizeof(output));
		ArcNode *temp;
		for(i = 0; i < m; i++)		//边链表
		{
			scanf("%d%d", &u, &v);
			u--; v--;
			count[v]++;
			temp = new ArcNode;
			temp->to = v; temp->next = NULL;	//构造邻接表
			if(List[u] == NULL) List[u] = temp;
			else
			{
				temp->next = List[u];
				List[u] = temp;
			}
		}

		TopSort();

		for(i = 0; i < n; i++)					//释放边链表上各边结点所占用的存储空间
		{
			temp = List[i];
			while(temp != NULL)
			{
				List[i] = temp->next;
				delete temp;
				temp = List[i];
			}
		}
	}
	return 0;
}

运行结果:


Ps:如有Bug,欢迎拍砖~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值