#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define NMAX 20//最大顶点个数
#define EMAX 20//最大的边数
#define NULL 0
#define InfoMax  999//用999表示正无穷
typedef int VexType;//图的顶点的数据类型
typedef float adjType;//图中边的带权值类型

/**************邻接矩阵表示*****************/
typedef struct Graph
{
	VexType vexs[NMAX+1];//一维数组 用于存储图中顶点的信息
	adjType arcs[NMAX+1][NMAX+1];//二维数组,用于存储图的邻接矩阵
	int e,n;//图当前的顶点数和边数
}Graph;
/****************************************/

/***************邻接表存储表示*********************/
typedef struct ENode
{
	VexType adjvex;//邻接顶点域
	adjType weight;//权值域
	struct ENode *next;
}ENode;
typedef struct GraphNode
{
	VexType vertex;//图中顶点的信息
	ENode *link;
}GraphNode;
/***********************************/

Graph *g;
GraphNode *gn;

void CreateGraph(Graph *G);
void DFSDeepth2(Graph *G,int i);
void BFSBreadth2(Graph *G,int k);
void CreateGraphNode(GraphNode *G);
void DFS_Deepth(GraphNode *G,int i);
void BFS_Breadth(GraphNode *G,int k);
void Dijkstra(Graph *G,int v0);//狄克斯特拉算法
void print_path(float dist[],int path[],int s[],int v0,int N);
void Floyd(Graph *G);//弗洛伊德算法
void Ppath(int path[][NMAX],int i,int j);
void Dispath(float A[][NMAX],int path[][NMAX],int n);

void main()
{
	int n,k,l;char ch;
	do
	{
		printf("\n\t\t==================================\n");
		printf("\t\t===1.邻接矩阵操作            =====\n");
		printf("\t\t===2.邻接表操作              =====\n");
		printf("\t\t===3.求最短路径              =====\n");
		printf("\t\t===4.退出                    =====\n");
		printf("\t\t==================================\n");
		printf("选择你要操作的类型:");

		scanf("%d",&k);
		switch(k)
		{
		case 1:
			g=(Graph *)malloc(sizeof(Graph));
			CreateGraph(g);
			printf("从第几个顶点开始遍历:");
			scanf("%d",&n);
			printf("\n从第%d个顶点开始深度遍历结果是:\n",n);
			DFSDeepth2(g,n);
			printf("\n从第%d个顶点开始广度遍历结果是:\n",n);
			BFSBreadth2(g,n);
			break;
		case 2:
			gn=(GraphNode *)malloc((NMAX+1)*sizeof(GraphNode));
			CreateGraphNode(gn);
			printf("从第几个顶点开始遍历:");
			scanf("%d",&n);
			printf("\n从第%d个顶点开始深度遍历结果是:\n",n);
			DFS_Deepth(gn,n);
			printf("\n从第%d个顶点开始广度遍历结果是:\n",n);
			BFS_Breadth(gn,n);
			break;
		case 3:
			if(g==NULL)
			{
				g=(Graph *)malloc(sizeof(Graph));
				CreateGraph(g);
			}
			//printf("\n第几个顶点的最短路径:");
			//scanf("%d",&l);
			//Dijkstra(g,l);

			printf("\n\t\t==弗洛伊德最短路径==\n");
			Floyd(g);
			break;
		default:
			break;
		}
		printf("\n\n\t\t==按任意键返回主菜单==\n\t\t");
		fflush(stdin);
		scanf("%c",&ch);
	}while(k!=4);
}

/************检测完毕************************/

//有向带权图的建立//邻接矩阵
void CreateGraph(Graph *G)
{
	int i,j,k,x,y;float w;
	printf("请输入顶点个数及边数:");
	scanf("%d%d",&x,&y);
	if(x>NMAX) printf("\n\t==ERROR==\n");
	for(i=1;i<=x;i++)
	{
		G->vexs[i]=i;
	}
	for(i=1;i<=x;i++)
	{
		for(j=1;j<=x;j++)
		{
			if(i==j) G->arcs[i][j]=0;
			else G->arcs[i][j]=InfoMax;
		}
	}

	if(y>EMAX) printf("\n\t==ERROR==\n");
	for(k=1;k<=y;k++)
	{//如果是非带权图,直接把权值设为1
		printf("\n请输入图中各边的起点终点及权值:");
		scanf("%d%d%f",&i,&j,&w);
		G->arcs[i][j]=w;
		//G->arcs[j][i]=w;
	}
	G->e=y;//边数
	G->n=x;//顶点个数
}

/**********深度优先遍历**********连通图***/
//邻接矩阵存储
int visit[NMAX+1];
void DFSDeepth2(Graph *G,int i)
{
	int j;
	printf("%-4d",G->vexs[i]);
	visit[i]=1;
	for(j=1;j<=G->n;j++)
	{
		if(G->arcs[i][j]!=0 && visit[j]==0)
			DFSDeepth2(G,j);
	}
}

/************检测完毕************************/

/***********广度优先遍历***连通图********/
//邻接矩阵存储

void BFSBreadth2(Graph *G,int k)
{
	int visit2[NMAX+1];
	int i,j,front,rear,q[NMAX+1];
	front=-1;rear=-1;
	for(i=0;i<=NMAX;i++)visit2[i]=0;
	printf("%-4d",G->vexs[k]);
	visit2[k]=1;
	rear=rear+1;
	q[rear]=k;
	while(rear!=front)
	{
		front=front+1;
		i=q[front];
		for(j=1;j<=G->n;j++)
		{
			if(G->arcs[i][j]>0 && visit2[j]==0)
			{
				printf("%-4d",G->vexs[j]);
				visit2[j]=1;
				rear=rear+1;
				q[rear]=j;
			}
		}
	}
}

/************检测完毕************************/

/***********邻接表存储,图的建立**************/
void CreateGraphNode(GraphNode *G)
{
	ENode *s;
	int i,j,k,x,y;
	printf("\n请输入图的顶点和边的个数:");
	scanf("%d%d",&x,&y);
	if(x>NMAX || y>EMAX)
		printf("\n\t===ERROR===\n");
	for(i=1;i<=x;i++)
	{
		G[i].vertex=i;
		G[i].link=NULL;
	}

	for(k=1;k<=y;k++)
	{
		printf("\t请输入图中的所有的边i,j:");
		scanf("%d%d",&i,&j);
		s=(ENode *)malloc(sizeof(ENode));
		s->adjvex=j;
		s->next=G[i].link;
		G[i].link=s;
		s=(ENode *)malloc(sizeof(ENode));
		s->adjvex=i;
		s->next=G[j].link;
		G[j].link=s;

	}
}

/************检测完毕************************/

/***********邻接表存储,深度优先遍历****************/
int visit3[NMAX+1];
void DFS_Deepth(GraphNode *G,int i)
{
	ENode *s;
	s=(ENode *)malloc(sizeof(ENode));
	printf("%-4d",G[i].vertex);
	visit3[i]=1;
	s=G[i].link;
	while(s!=NULL)
	{
		if(visit3[s->adjvex]==0)
			DFS_Deepth(G,s->adjvex);
		s=s->next;
	}
}

/************检测完毕************************/

/***********邻接表存储,广度优先遍历****************/

void BFS_Breadth(GraphNode *G,int k)
{
	int visit4[NMAX+1];
	int i,front,rear,q[NMAX+1];
	ENode *p;
	p=(ENode *)malloc(sizeof(ENode));
	for(i=0;i<NMAX+1;i++)visit4[i]=0;//
	front=-1;rear=-1;//队列初始化
	printf("%-4d",G[k].vertex);
	visit4[k]=1;
	rear=rear+1;
	q[rear]=k;
	while(rear!=front)
	{
		front=front+1;
		i=q[front];
		p=G[i].link;
		while(p!=NULL)
		{
			if(visit4[p->adjvex]==0)
			{
				printf("%-4d",G[p->adjvex].vertex);
				visit4[p->adjvex]=1;
				rear=rear+1;
				q[rear]=p->adjvex;
			}
			p=p->next;
		}
	}
}


/************邻接矩阵,最短路径***********************/
void Dijkstra(Graph *G,int v0)
{
	float distance[NMAX+1],wmin;
	int path[NMAX+1],s[NMAX+1];
	int i,u,num=1;
	for(i=1;i<=G->n;i++)
	{
		distance[i]=G->arcs[v0][i];
		s[i]=0;
		if(G->arcs[v0][v0]<InfoMax)
			path[i]=v0;
		else path[i]=0;
	}
	s[v0]=1;   //把源点放入s中
	path[v0]=0;
	do
	{
		wmin=InfoMax;
		u=v0;
		for(i=1;i<=G->n;i++)
			if(s[i]==0)
				if(distance[i]<wmin && distance[i]!=0)
				{
					u=i;
					wmin=distance[i];
				}
				s[u]=1;//把距离最小的顶点u放入s中
				for(i=1;i<=G->n;i++)
					if(s[i]==0)
					{
						if(distance[u]+G->arcs[u][i]<distance[i])
						{
							distance[i]=distance[u]+G->arcs[u][i];
							path[i]=u;
							//s[i]=1;
						}
					}
					num++;
	}while(num<=G->n);
	print_path(distance,s,path,v0,G->n);
}

void print_path(float dist[],int path[],int s[],int v0,int N)
{
	int i,k;
	printf("\n\t输出带权有向图的单源最短路径为:\n\t");
	for(i=1;i<=N;i++)
	{
		if(s[i]!=0)//s[3]=2???
		{
			k=i;
			printf("\n\t顶点%d到%d之间的路径为:",v0,i);
			while(k!=v0)
			{
				printf("%d<--",k);
				k=path[k];
			}
			printf("%d",k);
			printf(",最短路径长度为%f\n",dist[i]);
		}
		else 
			printf("\n\t顶点%d到%d之间没有路径!",v0,i);
	}
	printf("\n\t");
}

void Floyd(Graph *G)
{
	float A[NMAX][NMAX];
	int path[NMAX][NMAX],i,j,k;
	for(i=1;i<=G->n;i++)
		for(j=1;j<=G->n;j++)
		{
			A[i][j]=G->arcs[i][j];
			path[i][j]=-1;
		}
		for(k=1;k<=G->n;k++)
		{
			for(i=1;i<=G->n;i++)
				for(j=1;j<=G->n;j++)
					if(A[i][j]>A[i][k]+A[k][i])
					{
						A[i][j]=A[i][k]+A[k][i];
						path[i][j]=k;
					}
		}
		Dispath(A,path,G->n);
}

void Dispath(float A[][NMAX],int path[][NMAX],int n)
{
	int i,j;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
		{
			if(i!=j)
			{
				if(A[i][j]==InfoMax)
					printf("\n\t===从%s到%s没有路径\n",i,j);

				else
				{
					printf("\n\t===从%-4d到%-4d=>路径长度:%-4d===",i,j,A[i][j]);
					printf("\n\t==路径:%-4d",i);//起点
					Ppath(path,i,j);
					printf("%-4d\n",j);//终点
				}
			}
		}
}

void Ppath(int path[][NMAX],int i,int j)
{
	int k;
	k=path[i][j];
	if(k==-1)return;
	Ppath(path,i,k);
	printf("%-4d",k);
	Ppath(path,k,j);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值