学习记录-网的拓扑排序代码

下为要进行拓扑排序的图:

 


首先进行一些基础结构与操作的定义:

有关图的邻接存储:

typedef struct ArcNode{  //边表节点
	int adjvex;  //弧所指向的顶点的位置
	struct ArcNode *nextarc;  //指向下一条弧的指针;
	//InfoType info;  //网的边权值; 
}ArcNode;

typedef struct VNode{  //顶点表结点
	VertexType data;  //顶点信息
	ArcNode *firstarc;  //指向第一条依附该顶点的弧的指针 
}VNode,AdjList[MaxVertexNum];

typedef struct{
	AdjList vertices;  //邻接表
	int vexnum,arcnum;  //图的顶点数和弧数 
}Graph;                 //Graph是以邻接表存储的图的类型 

有关链栈: 

//链栈
typedef struct Linknode{
	VertexType data; //数据域
	struct Linknode *next; 
}Linknode,*LiStack;

//初始化(带头结点)(自写)
bool InitStack2(LiStack &S){
	S = (Linknode*)malloc(sizeof(Linknode));
	if(S==NULL)      //这里第一次写成=了!!!!!!!!!!! 
		return false;
	S->next = NULL;
	return true;
}

//链栈判空
bool IsEmpty(LiStack S){
	if(S->next == NULL)
		return true;
	else
		return false; 
} 
 
//链栈进栈(自写)
bool Push(LiStack &S,VertexType x){
	Linknode*p;
	p = (Linknode*)malloc(sizeof(Linknode));
	if(p==NULL)
		return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
//链栈出栈(自写2)
bool Pop(LiStack &S,VertexType &x) {
	if(S->next ==NULL)
		return false;
	x = S->next->data;
	S->next = S->next->next;
	return true;
}

   建立图的邻接表结构:

//建立图的邻接表结构
void CreateGraph(Graph *G){
	int i,j,k;
	ArcNode *e;
	
	//输入顶点数和边数
	printf("请输入顶点数和边数:\n");
	scanf("%d,%d",&G->vexnum,&G->arcnum); 
	
	//输入顶点信息,建立顶点表
	printf("请输入顶点字符:\n");
	for(i=0;i<G->vexnum;i++){
		scanf("%d",&G->vertices[i].data);
		G->vertices[i].firstarc=NULL;
	} 
	
	//建立边表
	for(k=0;k<G->arcnum;k++){
		printf("请输入边(vi,vj)上的顶点序号:\n");
		scanf("%d,%d",&i,&j);
		
		//单链表中的头插法
		e = (ArcNode*)malloc(sizeof(ArcNode));
		e-> adjvex = j;
		e->nextarc = G->vertices[i].firstarc;
		G->vertices[i].firstarc = e;
		
		//e = (ArcNode*)malloc(sizeof(ArcNode));
		//e-> adjvex = i;
		//e->nextarc = G->vertices[i].firstarc;
		//G->vertices[j].firstarc = e;
	} 
} 

输出图的邻接表结构:

void DispGraphAdjList(Graph *G)
{
	int i;
	ArcNode *p;
	printf("图的邻接表表示如下\n");
	printf("%6s%8s%12s\n","编号","顶点","相邻边编号");
	for(i=0;i< G->vexnum;i++)
	{
		printf("%4d %8d",i,G->vertices[i].data);//
		for(p=G->vertices[i].firstarc;p!=NULL;p=p->nextarc)
			printf("%4d",p->adjvex);
		printf("\n");
	}
}

拓扑排序及输出代码:

void TopologicalSort(Graph *G){
	printf("测试1:\n");
	//声明indegree数组,用来记录每个结点的当前入度。
	int indegree[5]={0,1,0,2,2};
	//声明print数组,用来记录生成的拓扑排序序列。
	int print[5]; 
	printf("测试1.1:\n");
	LiStack S;
	printf("测试1.2:\n");
	InitStack2(S);
	printf("测试1.3:\n");
	for(int i=0;i<G->vexnum;i++)
		if(indegree[i]==0)
			Push(S,i);
			
	int count = 0;
	printf("测试2:\n");
	while(!IsEmpty(S)){
		VertexType j;
		Pop(S,j);  //栈顶元素出栈,并命名为j 
		print[count++]=j;  //输出顶点j,储存到pirint数组中.
		ArcNode*p;
		for(p=G->vertices[j].firstarc;p;p=p->nextarc){
			//将所有i指向的顶点入度-1,并将入度减为0的顶点压入栈中。
			int v=p->adjvex;
			if(!(--indegree[v]))
				Push(S,v);
		} 
	}
	printf("测试3:\n");
	printf("拓扑排序如下:");
	for(int i=0;i<5;i++){
		printf("%d,",print[i]);
	}
}

主函数

int main(){
	Graph G;
	CreateGraph(&G);
	DispGraphAdjList(&G);
	TopologicalSort(&G);
	
	return 0;
}

完整代码:

#include <stdio.h>
#include <stdlib.h>

#define MaxVertexNum 20
//结点定义
typedef int VertexType;
 
typedef struct ArcNode{  //边表节点
	int adjvex;  //弧所指向的顶点的位置
	struct ArcNode *nextarc;  //指向下一条弧的指针;
	//InfoType info;  //网的边权值; 
}ArcNode;

typedef struct VNode{  //顶点表结点
	VertexType data;  //顶点信息
	ArcNode *firstarc;  //指向第一条依附该顶点的弧的指针 
}VNode,AdjList[MaxVertexNum];

typedef struct{
	AdjList vertices;  //邻接表
	int vexnum,arcnum;  //图的顶点数和弧数 
}Graph;                 //Graph是以邻接表存储的图的类型 

//建立图的邻接表结构
void CreateGraph(Graph *G){
	int i,j,k;
	ArcNode *e;
	
	//输入顶点数和边数
	printf("请输入顶点数和边数:\n");
	scanf("%d,%d",&G->vexnum,&G->arcnum); 
	
	//输入顶点信息,建立顶点表
	printf("请输入顶点字符:\n");
	for(i=0;i<G->vexnum;i++){
		scanf("%d",&G->vertices[i].data);
		G->vertices[i].firstarc=NULL;
	} 
	
	//建立边表
	for(k=0;k<G->arcnum;k++){
		printf("请输入边(vi,vj)上的顶点序号:\n");
		scanf("%d,%d",&i,&j);
		
		//单链表中的头插法
		e = (ArcNode*)malloc(sizeof(ArcNode));
		e-> adjvex = j;
		e->nextarc = G->vertices[i].firstarc;
		G->vertices[i].firstarc = e;
		
		//e = (ArcNode*)malloc(sizeof(ArcNode));
		//e-> adjvex = i;
		//e->nextarc = G->vertices[i].firstarc;
		//G->vertices[j].firstarc = e;
	} 
} 

//输出图的邻接表结构
void DispGraphAdjList(Graph *G)
{
	int i;
	ArcNode *p;
	printf("图的邻接表表示如下\n");
	printf("%6s%8s%12s\n","编号","顶点","相邻边编号");
	for(i=0;i< G->vexnum;i++)
	{
		printf("%4d %8d",i,G->vertices[i].data);//
		for(p=G->vertices[i].firstarc;p!=NULL;p=p->nextarc)
			printf("%4d",p->adjvex);
		printf("\n");
	}
}


//链栈
typedef struct Linknode{
	VertexType data; //数据域
	struct Linknode *next; 
}Linknode,*LiStack;

//初始化(带头结点)(自写)
bool InitStack2(LiStack &S){
	S = (Linknode*)malloc(sizeof(Linknode));
	if(S==NULL)      //这里第一次写成=了!!!!!!!!!!! 
		return false;
	S->next = NULL;
	return true;
}

//链栈判空
bool IsEmpty(LiStack S){
	if(S->next == NULL)
		return true;
	else
		return false; 
} 
 
//链栈进栈(自写)
bool Push(LiStack &S,VertexType x){
	Linknode*p;
	p = (Linknode*)malloc(sizeof(Linknode));
	if(p==NULL)
		return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
//链栈出栈(自写2)
bool Pop(LiStack &S,VertexType &x) {
	if(S->next ==NULL)
		return false;
	x = S->next->data;
	S->next = S->next->next;
	return true;
}


void TopologicalSort(Graph *G){
	printf("测试1:\n");
	//声明indegree数组,用来记录每个结点的当前入度。
	int indegree[5]={0,1,0,2,2};
	//声明print数组,用来记录生成的拓扑排序序列。
	int print[5]; 
	printf("测试1.1:\n");
	LiStack S;
	printf("测试1.2:\n");
	InitStack2(S);
	printf("测试1.3:\n");
	for(int i=0;i<G->vexnum;i++)
		if(indegree[i]==0)
			Push(S,i);
			
	int count = 0;
	printf("测试2:\n");
	while(!IsEmpty(S)){
		VertexType j;
		Pop(S,j);  //栈顶元素出栈,并命名为j 
		print[count++]=j;  //输出顶点j,储存到pirint数组中.
		ArcNode*p;
		for(p=G->vertices[j].firstarc;p;p=p->nextarc){
			//将所有i指向的顶点入度-1,并将入度减为0的顶点压入栈中。
			int v=p->adjvex;
			if(!(--indegree[v]))
				Push(S,v);
		} 
	}
	printf("测试3:\n");
	printf("拓扑排序如下:");
	for(int i=0;i<5;i++){
		printf("%d,",print[i]);
	}
	//if(count<G.vexnum)
		//return false;
	//else
		//return true;
}

 

int main(){
	Graph G;
	CreateGraph(&G);
	DispGraphAdjList(&G);
	TopologicalSort(&G);
	
	return 0;
}

我写代码中遇到的问题:

1.在链栈初始化中,把==写成了=:

//初始化(带头结点)(自写)
bool InitStack2(LiStack &S){
	S = (Linknode*)malloc(sizeof(Linknode));
	if(S=NULL)      //这里第一次写成=了!!!!!!!!!!! 
		return false;
	S->next = NULL;
	return true;
}

没有任何报错,却导致代码运行过程到此直接结束,没有后续的拓扑排序。

2.初始化时,将2号节点的入度误写为1,导致拓扑排序后的结果不正确。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值