#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
#define MaxVertices 100 //定义相关变量的最大值
#define MaxWeight 32767
#define MAXV 10
#define INF 32767
char Vertices[MaxVertices][MaxVertices]; //顶点信息的数组
typedef struct //无向图
{
int Edge[MaxVertices][MaxVertices]; //边的权信息的数组
int vexnum; //顶点数
int arcnum; //边数
}MGraph;
void CreateGraph(MGraph*G) //图的生成函数
{
int n,e,vi,vj,w,i,j;
printf("请输入图的顶点数和边数:");
scanf("%d%d", &n, &e);
G->vexnum = n; G->arcnum = e;
for (i=0;i<n;i++) //图的初始化
{
for (j=0;j<n;j++)
{
if (i==j)
G->Edge[i][j] = 0; //点自己到自己的长度为0
else
G->Edge[i][j] = 32767; //初始设置任意不同两点直接距离为无穷大
}
}
for (i=0;i<n;i++) //将顶点存入数组中
{
printf("请输入第%d个顶点的信息:",i+1);
scanf("%s",Vertices[i]);
}
for (i=0;i<G->arcnum;i++)
{
printf("请输入边的信息i,j,w:");
scanf("%d%d%d",&vi,&vj,&w);
//若为不带权值的图,则w输入1
//若为带权值的图,则w输入对应权值
G->Edge[vi - 1][vj - 1]=w;
G->Edge[vj - 1][vi - 1]=w; //无向图需加上此行
}
}
void Ppath(int path[][MaxVertices],int i,int j) //进行dfs深搜
{
int k;
k=path[i][j];
if(k==-1)
{
return;
}
Ppath(path,i,k);
printf("%s->",Vertices[k]);
Ppath(path,k,j);
}
//输出相应的路径,即任意两点间的路径和长度
void Dispath(int A[][MaxVertices],int path[][MaxVertices],int n)
{
int i, j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if (A[i][j]==INF)
{
if (i!=j)
{
printf("从%s到%s没有路径\n",Vertices[i],Vertices[j]);
}
}
else
{
printf("从%s到%s的最短路径长度为:%d ",Vertices[i],Vertices[j],A[i][j]);
printf("路径:%s->",Vertices[i]);
Ppath(path,i,j);//两点i,j之间还有其他中继结点,则循环套用次函数
printf("%s\n",Vertices[j]);
}
}
printf("\n");
}
}
void Floyd(MGraph* G)
{
int A[MaxVertices][MaxVertices],path[MaxVertices][MaxVertices];
int i,j,k;
//初始化
for (i= 0;i<G->vexnum;i++)
{
for (j=0;j<G->vexnum;j++)
{
A[i][j]=G->Edge[i][j]; //将路径中的数据全部导入二维数组A中
path[i][j]=-1;
}
}
//三重循环,floyd算法核心
for (k= 0;k<G->vexnum;k++)
{
for (i=0;i<G->vexnum;i++)
{
for (j=0;j<G->vexnum;j++)
{
if (A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
}
}
Dispath(A,path,G->vexnum);//输出函数
}
// 下为Kruskal
typedef struct Edge
{
int begin;
int end;
int weight;
}Edge;
//邻接矩阵转边集数组,按照权值排序,由小到大
void GraphEdgeArr(MGraph G,Edge edge[])
{
int i,j,k = 0;
Edge temp;
//将边数据填入edge中
for (i=0;i<G.vexnum;i++)
{
for (j=i+1;j<G.vexnum;j++)
{
if (G.Edge[i][j]!=MaxWeight) //有边
{
edge[k].begin=i;
edge[k].end=j;
edge[k].weight=G.Edge[i][j];
k++;
}
}
}
//冒泡排序
for(i=0;i<k; i++)
{
for (j=i+1;j<k;j++)
{
if (edge[j].weight<edge[i].weight)
{
temp=edge[i];
edge[i]=edge[j];
edge[j]=temp;
}
}
}
}
int findParent(int x,int parent[]) //找最终根节点
{
int xRoot=x;
while (parent[xRoot]!=-1)
{
xRoot=parent[xRoot];
}
return xRoot;
}
void unionXY(int x,int y,int parent[]) //连接两个节点的最终根节点
{
int xRoot=findParent(x,parent);
int yRoot=findParent(y,parent);
if (xRoot!=yRoot) //未连接
{
parent[xRoot]=yRoot;
}
}
int judgeUnion(int x,int y,int parent[]) //判断两个节点是否连接 1-是 0-否
{
int xRoot=findParent(x,parent);
int yRoot=findParent(y,parent);
if (xRoot==yRoot)
{
return 1;
}
else
{
return 0;
}
}
void Kruskal(MGraph G)
{
int i,j,temp;
Edge edges[100];
int parent[1000]={};
memset(parent,-1,sizeof(parent));
GraphEdgeArr(G,edges); //图中数据转化到edges中
for (i=0;i<G.vexnum;i++)
{
if (judgeUnion(edges[i].begin,edges[i].end,parent) == 0) //没有连接
{
unionXY(edges[i].begin,edges[i].end,parent); //则从小到大连接
cout<<Vertices[edges[i].begin]<<" -> "<<Vertices[edges[i].end]<<" = "<<edges[i].weight<<endl;
}
}
}
//菜单信息
void menu()
{
cout<<"\t\t导航系统" <<endl;
cout<<"\t\t1.录入路线信息" <<endl;
cout<<"\t\t2.两地点间最短路径"<<endl;
cout<<"\t\t3.校园导航"<<endl;
cout<<"请选择:";
}
int main()
{
MGraph G;
while (1) //无限循环
{
menu();
int select;
cin>>select;
switch (select) //根据用户选择进行匹配
{
case 1:
CreateGraph(&G);
break;
case 2:
Floyd(&G);
break;
case 3:
Kruskal(G);
break;
default:
break;
}
cout<<endl;
}
return 0;
}
/*
5 7
甲
乙
丙
丁
戊
1 2 2
1 3 4
1 4 3
2 3 1
2 5 4
3 5 2
4 5 2
*/
08-08
3055
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
09-30
06-30
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交