拓扑排序的C++实现(邻接表存图)

拓扑排序可以帮我们解决每两个物体之间有先后关系时遍历所有物体的问题,比如功课有先修后修关系时的排课表问题。

程序是用图模型来实现的,首先先用邻接表的存储模型来建立整个图,然后调用拓扑排序算法。其中,拓扑排序用到一个记录每个结点入度数的临时数组,还用到一个栈结构,用来存取入度数为0的结点。如果图中含有有向环时则输出提示信息。

#include <stack>
#include <memory>
#include <iostream>
#include <queue>
using namespace std;

struct LinkNode
{
	int vex; //邻接的结点在数组中的编号
	LinkNode* next;
};

//定义图结点的最大个数
const int MaxSize=10;

bool visited[10]={false};

//记录结点入度数的数组
int inCount[10];

struct Node
{
	int data;
	LinkNode* head;
} Adj[MaxSize];


//生成图(邻接表实现)
void createLink(int &numNode)
{
	int numLink=0;
	LinkNode* ptr;

	cin>>numNode;

	//初始化inCount数组
	memset(inCount,0,sizeof(int)*(numNode+1));

	for(int i=1;i<=numNode;++i)
	{
		Adj[i].head=0;
		cin>>Adj[i].data;
		cin>>numLink;

		//头插入建表
		for(int j=0;j<numLink;++j)
		{
			ptr=new LinkNode;
			cin>>ptr->vex;

			//vex下标所代表的点入度数加1
			++inCount[ptr->vex];

			ptr->next=Adj[i].head;
			Adj[i].head=ptr;
		}
	}
}

//拓扑排序
void tpSort(int& numNode)
{
	stack<int> stk;
	LinkNode* p=0;
	int showNum=0; //记录输出的结点的数目

	//在inCount数组中找出入度为0的结点,并分别入栈
	for(int i=1;i<=numNode;++i)
		if(inCount[i]==0)
			stk.push(i);

	//栈不为空时
	while(!stk.empty())
	{
		//出栈到v
		int v=stk.top();
		stk.pop();
		cout<<Adj[v].data<<" ";

		//将该点入度调为-1
		inCount[v]=-1;

		++showNum;
		//遍历以v为起点所临接的点
		p=Adj[v].head;
		while(p!=NULL)
		{
			//结点入度数减1
			--inCount[p->vex];
			//入度数为0时入栈
			if(inCount[p->vex]==0)
				stk.push(p->vex);

			p=p->next;
		}
	}

	cout<<endl;

	if(showNum<numNode) 
		cout<<"该图中含有有向环!"<<endl;
}


int main()
{
	int num=0;

	createLink(num);

	tpSort(num);

	return 0;
}



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值