图的邻接矩阵实现拓扑排序

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值