拓撲排序演算法實現可執行
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define MAX 20
typedef int VertexType;
typedef struct ArcNode//表結點
{
int adjvex;//弧所指向的頂點的位置
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode//頭結點
{
VertexType data;//頂點資訊
ArcNode *firstarc;//指向第一條依附該弧的頂點指標
}VNode,*AdjList;
typedef struct
{
AdjList vertices;
int vexnum;//圖的**當前**頂點數
}ALGraph;
typedef struct//棧的定義
{
int *base;
int *top;
int stacksize;
}SqStack;
/////////棧的操作函式定義
void initialStack(SqStack *s)
{
s->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
if(!s->base) exit(0);
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
}
void Push(SqStack *s,int e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(int *)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(int));
if(!s->base) exit(0);
s->top=s->base+s->stacksize;
s->stacksize+=STACKINCREMENT;
}
*(s->top)++=e;
}
void Pop(SqStack *s,int *e)
{
if(s->top==s->base) exit(0);
*e=*--(s->top);
}
void GetTop(SqStack *s,int *e)
{
if(s->top==s->base) exit(0);
*e=*(s->top-1);
}
int StackEmpty(SqStack *s)
{
if(s->base==s->top)
return(1);
else
return(0);
}
/////建立圖的鄰接矩陣
void CreatAjacentMatrix(int *array,int n)//建立鄰接矩矩陣(n行n列)
{
int a;
int i,j,flag=0;
printf("請輸入一個%d行%d列的關於圖的鄰接矩陣:\n",n,n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
scanf("%d",&a);
*(array+i*n+j)=a;
}
}
void PrintAjacentMatrix(int *array,int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%5d ",*(array+i*n+j));
printf("\n");
}
}
////將鄰接矩陣匯出為圖的鄰接表形式
void CreatAdjList(int *array,int n,ALGraph *G)
{
int i,j;
ArcNode *p;//表結點
G->vexnum=n;//初始化頂點數
G->vertices=(VNode *)malloc((n+1)*sizeof(VNode));//頭結點陣列,開闢n+1長度的陣列空間
for(i=1;i<=n;i++)//初始化頭結點陣列
{
G->vertices[i].data=i;
G->vertices[i].firstarc=NULL;
}
//////////
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(*(array+i*n+j)==1)
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j+1;
p->nextarc=G->vertices[i+1].firstarc;
G->vertices[i+1].firstarc=p;
}
}
}
/*void FindInDegree(ALGraph G,int *indegree)//對頂點求入度
{
int i,j;
ArcNode *p;
for(i=1;i<=G.vexnum;i++)
indegree[i]=0;//indispensable
for(i=1;i<=G.vexnum;i++)//對每個結點跑完整個鄰接表
for(j=1;j<=G.vexnum;j++)
for(p=G.vertices[j].firstarc;p;p=p->nextarc)
if(G.vertices[i].data==p->adjvex)//==
{indegree[i]++; printf("%d\n",p->adjvex);
}
}*/
void FindInDegree(ALGraph G,int *indegree){
ArcNode *p=NULL;
int x=0;
for(int i=1;i<=G.vexnum;i++)
indegree[i]=0;
for(int i=1; i<G.vexnum; i++) {
p=G.vertices[i].firstarc;
while(p!=NULL) {
x=p->adjvex;
printf("%d\n",x);
indegree[x]++;
p=p->nextarc;
}
}
}
/////////拓撲排序演算法
int TopologicalSort(ALGraph G)
{
//有向圖採用鄰接表儲存結構
//若G無迴路,則flag=0,輸出G的頂點的一個拓撲序列,否則給出該有向圖有迴路的提示.
int i,count,k;
int *indegree=(int *)malloc((G.vexnum+1)*sizeof(int));
SqStack S;
ArcNode *p;
FindInDegree(G,indegree);//對頂點求入度indegree[G.vexnum]
initialStack(&S);//為避免重複檢測入度為0的頂點,可另設一棧暫存放所有入度為0的頂點
for(i=1;i<=G.vexnum;i++)
if(!indegree[i])
Push(&S,i);//0入度點進棧
count=0;//對輸出頂點計數,作為判斷是否有迴路的根據
while(!StackEmpty(&S))
{
Pop(&S,&i);
printf("%d ",i);//輸出i號頂點並計數
count++;
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;//表結點的資料域,即對i號頂點的每個鄰接點的入度減1
if(!(--indegree[k]))//若入度減少為0,則入棧
Push(&S,k);
}
}
if(count<G.vexnum)//該有向圖有迴路
return 0;
else
return 1;
}
int main()
{
int n;
int *A;
ALGraph G;
printf("請輸入你想建立的鄰接矩矩陣的行列數(即頂點數):\n");
scanf("%d",&n);
A=(int *)malloc(n*n*sizeof(int));
CreatAjacentMatrix(A,n);
printf("請輸出圖的鄰接矩陣A:\n");
PrintAjacentMatrix(A,n);
CreatAdjList(A,n,&G);
printf("該有向圖的一個拓撲排序結果如下所示:\n");
if(TopologicalSort(G))
printf("\n");
else
printf("該有向圖有迴路!\n");
return 0;
}