/***************************** title : 拓扑排序(邻接矩阵实现) author: jay chang date : 2009/07/14 *****************************/ #include<iostream> using namespace std; #define MAXSIZE 99 #define FALSE 0 #define TRUE 1 typedef char VertexData; typedef int AdjType; typedef struct VertexNode { VertexData vertexData; }VertexNode; typedef struct ArcNode { AdjType adj; //弧的权值 }ArcNode; typedef struct AdjMatrix { VertexNode vertexNodes[MAXSIZE+1]; ArcNode arcNodes[MAXSIZE+1][MAXSIZE+1]; int vertexNum,arcNum; }AdjMatrix; typedef struct Queue { int data[MAXSIZE+1]; int head,rear; }Stack; /********************************************************************************** Function Name:LocateGraph Return Type: int Function Description: 查询在图中是否存在结点信息为vertexData的结点,存在返回结 点位置,否则返回FALSE。 **********************************************************************************/ int LocateGraph(AdjMatrix* g,VertexData vertexData) { int iIndex; for(iIndex=1;iIndex<=g->vertexNum;iIndex++) { if(vertexData==g->vertexNodes[iIndex].vertexData) return iIndex; } return FALSE; } /********************************************************************************** Function Name:InitAdjMatrix Return Type: void Function Description: 初始化有向无环图 **********************************************************************************/ inline void InitAdjMatrix(AdjMatrix* g) { for(int iIndex=1;iIndex<=g->vertexNum;iIndex++) { for(int jIndex=1;jIndex<=g->vertexNum;jIndex++) { g->arcNodes[iIndex][jIndex].adj=0; } } } /********************************************************************************** Function Name:CreateAdjMatrix Return Type: void Function Description: 创建连通图 **********************************************************************************/ void CreateAdjMatrix(AdjMatrix* g) { cout<<"******************************************************************\n"; cout<<" 拓扑排序\n"; cout<<"******************************************************************\n"; cout<<"输入连通图的顶点数,弧数:\n"; cin>>g->vertexNum>>g->arcNum; cout<<"输入顶点信息"<<endl; int iCount,start,end;char arcStart,arcEnd; InitAdjMatrix(g); for(iCount=1;iCount<=g->vertexNum;iCount++) { cout<<"结点"<<iCount<<"的信息"<<endl; cin>>g->vertexNodes[iCount].vertexData; } for(iCount=1;iCount<=g->arcNum;iCount++) { cout<<"输入第"<<iCount<<"条弧的起始,终点"<<endl; cin>>arcStart>>arcEnd; start=LocateGraph(g,arcStart);end=LocateGraph(g,arcEnd); g->arcNodes[start][end].adj=1; } } /********************************************************************************** Function Name:FindID Return Type: void Function Description: 计算每个顶点的入度 **********************************************************************************/ void FindID(AdjMatrix* g,int indegree[]) { for(int jIndex=1;jIndex<=g->vertexNum;jIndex++) { for(int iIndex=1;iIndex<=g->vertexNum;iIndex++) { if(g->arcNodes[iIndex][jIndex].adj==1) { indegree[jIndex]++; } } } } /********************************************************************************** Function Name:QueueOperation Function Description: 队列的基本操作 **********************************************************************************/ inline void InitQueue(Queue* queue) { queue->head=0; queue->rear=0; } inline bool IsEmpty(Queue* queue) { return queue->head%MAXSIZE==queue->rear?true:false; } inline void Quit(Queue* queue,int* i) { *i=queue->data[queue->head++]; } inline int Enter(Queue* queue,int value) { if(queue->head==((queue->rear+1)%MAXSIZE)) return FALSE; queue->data[queue->rear++]=value; return TRUE; } /********************************************************************************** Function Name:ClearZero Return Type: int Function Description: 删除以顶点i为起点的弧 **********************************************************************************/ inline void ClearZero(AdjMatrix* g,int iIndex,int indegree[],Queue* queue) { int jIndex; for(jIndex=1;jIndex<=g->vertexNum;jIndex++) { if(g->arcNodes[iIndex][jIndex].adj>0) { g->arcNodes[iIndex][jIndex].adj=0; indegree[jIndex]--; if(indegree[jIndex]==0) Enter(queue,jIndex); } } } /********************************************************************************** Function Name:TopoSort Return Type: int Function Description: 拓扑排序 **********************************************************************************/ int TopoSort(AdjMatrix* g) { int indegree[MAXSIZE+1]={0},count; Queue queue; FindID(g,indegree); InitQueue(&queue); int iCount; for(iCount=1;iCount<=g->vertexNum;iCount++) { if(indegree[iCount]==0) Enter(&queue,iCount); } count=0; while(!IsEmpty(&queue)) { Quit(&queue,&iCount); cout<<g->vertexNodes[iCount].vertexData<<" "; //输出顶点并计数 count++; ClearZero(g,iCount,indegree,&queue); //删除以顶点i为起点的弧 } cout<<endl; return count==g->vertexNum?TRUE:FALSE; } int main() { AdjMatrix *g=(AdjMatrix*)malloc(sizeof(AdjMatrix)); InitAdjMatrix(g); CreateAdjMatrix(g); TopoSort(g); return 0; }