1.AOV网:有向图中,顶点表示活动,弧表示优先关系的网
(1)AOV网中不能出现回路,回路意味着某活动的开始要以自己的结束为先决条件,这是矛盾的
(2)采用拓扑排序判断是否存在回路
2.拓扑排序的思想
(1)从AOV网中选择一个没有前驱的顶点并输出
(2)从AOV网中删除该顶点,并且删去所有以该顶点为尾的弧
(3)重复上述操作,直到输出全部顶点,或AOV网中不存在没有前驱的顶点
3.程序相关
(1)图的存储结构:邻接表
(2)求顶点的入度:在邻接表中增加入度域in
(3)找没有前驱的顶点:采用栈存储入度为0的顶点入栈
(4)时间复杂度:设有n个顶点,e条边,则为O(n+e)
其中O(n)是入度为0的顶点入栈,O(e)程序中的while语句
#include <iostream>
using namespace std;
const int Maxsize=10;
struct EdgeNode{//边表结点
int adjvex;
EdgeNode *next;
};
struct VertexNode{//顶点表结点
string vertex;
int in;//增加入度域
EdgeNode *firstEdge;
};
class AovGraph{
public:
AovGraph(string a[],int n,int e);
~AovGraph();
void TopSort();
private:
VertexNode adjlist[Maxsize];//存放顶点表的数组
int vertexNum,edgeNum;
};
AovGraph::AovGraph(string a[],int n,int e){
int i,j,k;
EdgeNode *s=NULL;
vertexNum=n;edgeNum=e;
for(i=0;i<vertexNum;i++){//初始化顶点表
adjlist[i].vertex=a[i];
adjlist[i].firstEdge=NULL;
}
for(k=0;k<edgeNum;k++){
cout<<"请输入边的两个顶点:";
cin>>i>>j;
s=new EdgeNode;
s->adjvex=j;
s->next=adjlist[i].firstEdge;//将结点s插入表头
adjlist[i].firstEdge=s;
}
for(i=0;i<vertexNum;i++){
cout<<"请依次输入每个顶点的入度:"<<endl;
cin>>adjlist[i].in;
}
}
AovGraph::~AovGraph(){
EdgeNode *p,*q;
p=q=NULL;
for(int i=0;i<vertexNum;i++){
p=q=adjlist[i].firstEdge;
while(p!=NULL){
p=p->next;
delete q;
q=p;
}
}
}
void AovGraph::TopSort(){
int i,j,k,count=0;
int s[Maxsize],top=-1;//顺序栈,初始化
EdgeNode *p=NULL;
for(i=0;i<vertexNum;i++)
if(adjlist[i].in==0)
s[++top]=i;//入度为0的顶点入栈
while(top!=-1){
j=s[top--];
cout<<adjlist[j].vertex<<",";
count++;
p=adjlist[j].firstEdge;
while(p!=NULL){
k=p->adjvex;
adjlist[k].in--;
if(adjlist[k].in==0)
s[++top]=k;
p=p->next;
}
}
if(count<vertexNum)
cout<<"存在回路"<<endl;
}
int main()
{
string ch[6]={"A","B","C","D","E"};
AovGraph alg(ch,5,5);
alg.TopSort();
cout<<endl;
return 0;
}
运行结果
请输入边的两个顶点:0 1
请输入边的两个顶点:0 2
请输入边的两个顶点:1 3
请输入边的两个顶点:1 4
请输入边的两个顶点:2 4
请依次输入每个顶点的入度:
0
请依次输入每个顶点的入度:
1
请依次输入每个顶点的入度:
1
请依次输入每个顶点的入度:
1
请依次输入每个顶点的入度:
2
A,B,D,C,E,
Process returned 0 (0x0) execution time : 20.274 s
Press any key to continue.