拓扑排序可以帮我们解决每两个物体之间有先后关系时遍历所有物体的问题,比如功课有先修后修关系时的排课表问题。
程序是用图模型来实现的,首先先用邻接表的存储模型来建立整个图,然后调用拓扑排序算法。其中,拓扑排序用到一个记录每个结点入度数的临时数组,还用到一个栈结构,用来存取入度数为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;
}