1、基本概念:
有序图,每个顶点都有前驱和后继的关系。
现实生活中我们可以用一个有向图来表示一个工程,顶点表是活动,有向边A———->B表示:A必须先于活动B进行。这种有向图叫做“ 顶表示活动的网络(activity on vertices)”
——记作AOV网络。
将全部顶点都排在一个线性有序的序列中。这种构造AOV网络全部顶点的拓扑有序序列的运算就叫做拓扑排序(topological sorting)
2、步骤:
(1)选择一个没有直接前驱的顶点,并输出;
(2)从图中删除该顶点,同时删去所有它发出的有向边;
(3)依次循环以上两步,直到:全部顶点已经输出(排序结束),或被迫跳出循环(图中存在环)
(注意理解代码中有个模仿栈结构的top“指针”和count入度数组)
void TopologicalSort()
{
int i,top=-1;
for(i = 0;i<numVertexs;++i)
{
if(count[i] == 0)
{
count[i] = top;
top = i;//top是用下标表示
}
}
for(i = 0;i<numVertexs;++i)
{
if(top == -1)
cout<<"Have a circle..."<<endl;
else
{
int j = top;
top = count[j];
cout<<myv[j].data<<"-->";
EdgeNode *l = myv[j].link;
while(l)
{
int k = l->dest;
if(--count[k] == 0)//这里的--是将l所指出去相连的边都删掉。
{
count[k] = top;
top = k;
}
l = l->next;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include"AllHead.h"
#define MAXSIZE 20
//单向图。
class EdgeNode;
template<class T>
class GrapHVec;
template<class T>
class VertexList
{
friend class GrapHVec<T>;
private:
T data;
EdgeNode *link;
public:
VertexList():link(NULL)
{}
~VertexList(){}
};
class EdgeNode
{
public:
int dest;
EdgeNode *next;
public:
EdgeNode()
{
next = NULL;
}
~EdgeNode(){}
};
template<class T>
class GrapHVec
{
private:
VertexList<T> *myv;
int maxSize;//最大
int numVertexs;
int numEdges;
int *count;//建立一个入度数组
public:
GrapHVec(int sz=MAXSIZE)
{
maxSize = sz<=MAXSIZE?MAXSIZE:sz;
myv = new VertexList<T>[maxSize];
count = new int[maxSize];
for(int i=0;i<maxSize;++i)
count[i] = 0;
numVertexs = 0;
numEdges = 0;
}
~GrapHVec(){}
public:
int GetNextNeighbor(T x1,T x2)
{
if(numVertexs == 0)
{
cout<<"空(GetFirstNeighbor)...";
return ERROR;
}
int v1 = GetVerticespos(x1);
int v2 = GetVerticespos(x2);
EdgeNode *fp = myv[v1].link;
while(fp!=NULL && (*fp).dest != v2)
fp = (*fp).next;
if(fp == NULL)
{
//cout<<"不存在有过链接.....";
return -1;
}
fp = (*fp).next;
if(fp != NULL)
return (*fp).dest;
else
{
//cout<<"没有下一个结点....";
return -1;
}
}
int GetFirstNeighbor(T x)
{
if(numVertexs == 0)
{
cout<<"空(GetFirstNeighbor)...";
return ERROR;
}
int v = GetVerticespos(x);
EdgeNode *fp = myv[v].link;
if(fp != NULL)
return (*fp).dest;
else
{
cout<<x<<" :没有链接的结点....";
return ERROR;
}
}
int GetVerticespos(T x)
{
if(numVertexs == 0)
{
cout<<"空(Getpos)....";
return FALSE;
}
int i;
for(i=0;i<numVertexs;i++)
{
if(myv[i].data == x)
return i;
}
return -1;
}
public:
int NumOfVertices(){return numVertexs;}
int NumOfEdge(){return numEdges;}
int InsertVertex(T x)
{
if(numVertexs >= maxSize)
{
cout<<"空间已满不能插入...."<<endl;
return ERROR;
}
myv[numVertexs++].data = x;
return TRUE;
}
int InsertEdge(T x1,T x2)//A,B:A-->B
{
int v1 = GetVerticespos(x1);//A
int v2 = GetVerticespos(x2);//B
if(v1 == -1||v2 == -1)
{
cout<<"有一个节点不存在"<<endl;
return ERROR;
}
EdgeNode *p1 = new EdgeNode;
(*p1).dest = v2;
(*p1).next = myv[v1].link;
myv[v1].link = p1;
count[v2]++;
++numEdges;
}
void showVecGrap()
{
for(int i=0; i<numVertexs; ++i)
{
cout<<i<<":>"<<myv[i].data<<"-->";
EdgeNode *e = myv[i].link;
while(e != NULL)
{
cout<<e->dest<<"-->";
e = e->next;
}
cout<<"Nul."<<endl;
}
}
public:
void TopologicalSort()
{
int i,top=-1;
for(i = 0;i<numVertexs;++i)
{
if(count[i] == 0)
{
count[i] = top;
top = i;//top是用下标表示
}
}
for(i = 0;i<numVertexs;++i)
{
if(top == -1)
cout<<"Have a circle..."<<endl;
else
{
int j = top;
top = count[j];
cout<<myv[j].data<<"-->";
EdgeNode *l = myv[j].link;
while(l)
{
int k = l->dest;
if(--count[k] == 0)//这里的--是将l所指出去相连的边都删掉。
{
count[k] = top;
top = k;
}
l = l->next;
}
}
}
}
};
#include"graphvec.h"
int main()
{
GrapHVec<char> tp;
tp.InsertVertex('A');
tp.InsertVertex('B');
tp.InsertVertex('C');
tp.InsertVertex('D');
tp.InsertVertex('E');
tp.InsertVertex('F');
tp.InsertEdge('A','B');
tp.InsertEdge('A','C');
tp.InsertEdge('A','D');
tp.InsertEdge('C','F');
tp.InsertEdge('D','F');
tp.InsertEdge('D','B');
tp.InsertEdge('E','C');
tp.InsertEdge('E','F');
tp.showVecGrap();
cout<<"========================="<<endl;
tp.TopologicalSort();
return 0;
}