#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);
}
图
最新推荐文章于 2024-05-31 09:05:13 发布