数据结构:图(C语言)

实现图的创建,广度,深度遍历,拓扑排序。

#include<stdio.h>
#define MAXQSIZE 50
#define MVNum 50
#define error MVNum+10
#define OVERFLOW 0
typedef int Status;
#define OK 1
#define ERROR 0
#define null -1
#include "stdlib.h"
#include "string.h"

typedef struct arcnode{
	int adjvex;
	struct arcnode *nextatc;
}arcnode;

typedef struct vnode{
	int data;
	arcnode *firstarc;
}vnode,adjlist[MVNum];

typedef struct{
	adjlist vertices;	  //特殊数组
	int vexnum,arcnum;   //顶点数,边数
}algraph;

//循环队列定义
typedef struct
	{
		int *base;
			int front;
		int rear;
 	} 	SqQueue;
//循环队列的初始化
Status InitQueue(SqQueue &Q)
	{
		Q.base=new int[MAXQSIZE];
		if(!Q.base)
			return(OVERFLOW);
		Q.front=Q.rear=0;
		return OK;
 	} 
 //入队
 Status EnQueue(SqQueue &Q,int e)
 	{
 		if((Q.rear+1)%MAXQSIZE==Q.front)
 			return ERROR;
 		Q.base[Q.rear]=e;
 		Q.rear=(Q.rear+1)%MAXQSIZE;
 		return OK;
 	 } 
 //出队
 Status DeQueue(SqQueue &Q,int &e)
	 {
 		if(Q.front==Q.rear) 
			return ERROR;
 		e=Q.base[Q.front];
 		Q.front=(Q.front+1)%MAXQSIZE;
 		return OK;
  	} 

 int pankong(SqQueue Q)
  	{
  		if(Q.front==Q.rear) return 1;
  			return 0;
  	 } 

//栈的定义 (实数栈)
typedef struct StackNode1
	{
		float data;
		struct StackNode1 *next;
	}StackNode1,*LinkStack1;
//栈的初始化 (实数栈)
Status InitStack1(LinkStack1 &S)
	{
		S=NULL;
		return OK;
	} 
//判断栈是否为空(实数栈)
int StackEmpty1(LinkStack1 S)
	{
		if(S==NULL)return 1;
		return 0;
	 } 
//入栈 (实数栈)
Status Push1(LinkStack1 &S,int e)
	{
		LinkStack1 p;
    	p=(LinkStack1)malloc(sizeof(StackNode1));
		p->data=e;
		p->next=S;
		S=p;
		return OK;
	}
//出栈 (实数栈)
Status Pop1(LinkStack1 &S,int &e)
	{
		LinkStack1 p;
		if(S==NULL) return ERROR;
		e=S->data;
		p=S;
		S=S->next;
		delete p;
		return OK;
	}





//找出节点位置
int location(algraph g,int h){
	for(int i = 0;i<g.vexnum ;i++){
		if(g.vertices[i].data ==h)
			return i;
	}
}

//创建一个邻接表
void createudg(algraph *g,algraph *s){
	int ww[MVNum];
	printf("请输入顶点个数:\n");
	scanf("%d",&g->vexnum);
	s->vexnum = g->vexnum ;

	printf("请输入边数:\n");
	scanf("%d",&g->arcnum);
	s->arcnum = g->arcnum ;

	printf("请输入%d个顶点的值:\n",g->vexnum);
	for(int i = 0;i<g->vexnum;i++){
		scanf("%d",&ww[i]);}

	
	for(int i = 0;i< g->vexnum ; i++){
		g->vertices[i].data = ww[i];
		s->vertices[i].data = ww[i];
		g->vertices[i].firstarc = NULL;
		s->vertices[i].firstarc = NULL;

	}



	printf("请输入各个边的两点值:\n");
	for(int i=0 ; i < g->arcnum ; i++){
		int j,k;
		scanf("%d",&j);
		scanf("%d",&k);
		int w = location(*g,j);
		int m = location(*g,k);
		//printf("%d,%d",w,m);
		arcnode *p1 = new arcnode;
		p1->adjvex = m;
		p1->nextatc = g->vertices[w].firstarc;
		g->vertices[w].firstarc = p1;

		arcnode *p2 = new arcnode;
		p2->adjvex = w;
		p2->nextatc = s->vertices[m].firstarc;
		s->vertices[m].firstarc = p2;

	}
	printf("邻接表,逆邻接表创建成功。\n");
}



//深度优先搜索
void dfs_al(algraph g,int v,int a[]){

	a[v] = 1;
	arcnode *p1;
	p1 = g.vertices[v].firstarc;
	printf("%d\t",g.vertices[v].data);
	while(p1!=NULL){
		int w = p1->adjvex;
		if(!a[w])
			dfs_al(g,w,a);
		p1= p1->nextatc;
	}
}
//返回下一个元素
int firstadj(algraph g,int v){
	int h;
	arcnode *p1 = new arcnode;
	p1 = g.vertices[v].firstarc;
	
	if(p1==NULL)
		return -1;
	h = p1->adjvex;
	return h;
}

//返回下下一个
int nextadj(algraph g,int v,int w){
	arcnode *p1 = new arcnode;
	arcnode *p2 = new arcnode;
	p1 = g.vertices[v].firstarc;
	while(1){
		if(p1->nextatc==NULL)
			return -1;
		p2=p1->nextatc;
		if(p1->adjvex == w)
			return p2->adjvex;
		p1=p2;
	}
	
	
}
//广度优先搜索
void bfs_al(algraph g,int v,int a[]){
	SqQueue S4;
	int u,w;
	InitQueue (S4);
	a[v] = 1;
	EnQueue(S4,v);
	while(!pankong(S4)){
		DeQueue(S4,u);
		printf("%d\t",g.vertices[u].data);
		for(w=firstadj(g,u);w>=0;w=nextadj(g,u,w)){
			if(!a[w]){
				a[w] = 1;
				EnQueue(S4,w);
			}
		}
	}
}
//确定度数
int findindeggre(algraph g,int v){
	int ww=0;
	arcnode *p = new arcnode;
	p=g.vertices[v].firstarc;
	if(p==NULL)
		return 0;
	while(p!=NULL){
		p=p->nextatc;
		ww++;
	}
	return ww;

}


//拓扑排序
int topolog(algraph g,algraph s,int a[]){
	int indegree[MVNum],u,k;
	arcnode *p = new arcnode;
	for(int i = 0;i<g.vexnum;i++)
		indegree[i]=findindeggre(s,i);

	LinkStack1 S;
	InitStack1(S);
	for(int i=0;i<g.vexnum ;i++)
		if(!indegree[i])
			Push1(S,i);
	int m=0;
	while(!StackEmpty1(S)){
		Pop1(S,u);
		a[m]=u;
		++m;
		p=g.vertices[u].firstarc;
		while(p!=NULL){
			k=p->adjvex;
			--indegree[k];
			if(indegree[k]==0)
				Push1(S,k);
			p=p->nextatc;
		}
	}
	if(m<g.vexnum)
		return ERROR;
	else
		return OK;
}


void main(){
	int v;
	int visited[MVNum],top[MVNum];
	algraph G,SS;
	createudg(&G,&SS);
	

	printf("\n----------------------------------------\n\n");
	printf("\n请输入从第几个顶点开始遍历:\n");
	scanf("%d",&v);
	v-=1;
	for(int i = 0;i<G.vexnum;i++)
		visited[i]=0;
	printf("深度优先遍历为:\n");
	dfs_al(G,v,visited);

	for(int i = 0;i<G.vexnum;i++)
		visited[i]=0;
	printf("\n广度优先遍历为:\n");
	bfs_al(G,v,visited);
	printf("\n----------------------------------------\n\n");
	printf("\n拓扑排序后顺序为:\n");
	int c=topolog(G,SS,top);
	if(c==0)
		printf("图中有回路存在\n");
	else{
		for(int i=0;i<G.vexnum ;i++){
			int lc,ly;
			lc=top[i];
			ly=G.vertices[lc].data;
			printf("%d\t",ly);
		}
	}
	printf("\n----------------------------------------\n\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值