#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<malloc.h>
#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 2
typedef int Status;
#define INFINITY INT_MAX
typedef int VRType;
#define MAX_VERTEX_NUM 26
enum GraphHand{DG, DN, UDG, UDN};
typedef struct{
VRType adj;//顶点关系类型,对于无权图用0,1表示相邻否,带全图,图为权值
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵结构
typedef struct {
int in_degree; //该顶点的入度
int pos; //该顶点在图中数组中的位置
}VertexType; //顶点结构,包含顶点中应该包含的信息
typedef struct{
VertexType vex[MAX_VERTEX_NUM]; //顶点向量,存储顶点中包含的信息
AdjMatrix arcs; //图的邻接矩阵
int vexnum, arcnum; //图的顶点数和边数
GraphHand kind; //图的类型
}MGraph;
void Input_MGraph(MGraph &G)
{
printf("input the number of vertex=");
scanf("%d",&G.vexnum);
G.kind = DN; //图的类型是有向图
G.arcnum = 0;
printf("input the adjacent matrix of graph\n");
int i,j;
for(i = 0; i < G.vexnum; i++) //输入有向图的邻接矩阵
for(j = 0; j < G.vexnum; j++)
scanf("%d", &(G.arcs[i][j].adj));
printf("\n");
for(i = 0; i < G.vexnum; i++) //给图的顶点赋值
{
G.vex[i].in_degree = 0;
G.vex[i].pos = i;
}
for(j = 0; j < G.vexnum; j++) //求图中所有顶点的入度
for(i = 0; i < G.vexnum; i++){
if(G.arcs[i][j].adj == 1){
G.vex[j].in_degree++;
G.arcnum++; //求出图中边的数目
}
}
}
void Print_MGraph(MGraph G)
{
int i, j;
for(i = 0; i < G.vexnum; i++){
for(j = 0; j < G.vexnum; j++){
printf("%d ",G.arcs[i][j].adj);
}
printf("\n");
}
printf("%d\n", G.arcnum);
for(i = 0; i < G.vexnum; i++)
printf("%d ",G.vex[i].in_degree);
printf("\n");
}
typedef VertexType SElemType;
struct SqStack
{
SElemType *base;
SElemType *top;
int stacksize;
};
void InitStack(SqStack &S)
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base)
exit(-1);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
void DestroyStack(SqStack &S)
{
free(S.base);
S.top=S.base=NULL;
S.stacksize=0;
}
void ClearStack(SqStack &S)
{
S.top=S.base;
}
int StackEmpty(SqStack S)
{
if(S.top==S.base)
return 1;
else
return 0;
}
int StackLength(SqStack S)
{
return S.top-S.base;
}
int GetTop(SqStack S,SElemType &e)
{
if(S.top>S.base)
{
e=*(S.top-1);
return 1;
}
else
return 0;
}
void Push(SqStack &S,SElemType e)
{
if(S.top-S.base==S.stacksize)
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));
if(!S.base)
exit(-1);
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INCREMENT;
}
*(S.top)++=e;
}
int Pop(SqStack &S,SElemType &e)
{
if(S.top==S.base)
return 0;
e=*--S.top;
return 1;
}
int TopologicalSort(MGraph G){
SqStack s;
InitStack(s);
int i;
int count = G.vexnum;
for(i = 0; i < G.vexnum; i++) //首先将图中所有入度为0的结点进栈
if(G.vex[i].in_degree == 0)
{
Push(s, G.vex[i]);
}
while(!StackEmpty(s)){
VertexType e;
Pop(s,e);
printf("拓扑排序输出第%d个结点\n",e.pos+1);
count--;
int j;
for(j = 0; j < G.vexnum; j++){ //删除所有与删除结点有关的边
if(G.arcs[e.pos][j].adj == 1)
{
G.arcs[e.pos][j].adj = 0; //在邻接矩阵中删除该边
G.vex[j].in_degree--; //删除该边后,该边弧头所在的顶点的入度减1
G.arcnum--; //图中的边数减1
if(G.vex[j].in_degree == 0) //如果该边所在弧头的入度为0,则将该顶点进栈
Push(s, G.vex[j]);
}
}
}
if(count == 0)
printf("该图不含有回路\n");
else
printf("该图含有回路\n");
return 1;
}
int main()
{
MGraph G;
Input_MGraph(G);
TopologicalSort(G);
return 0;
}
图的邻接矩阵实现拓扑排序
最新推荐文章于 2021-01-30 21:03:50 发布