您的位置:首页 > 编程语言 > C语言/C++

c语言之邻接矩阵&最短路径&最小生成树

2017-12-20 19:47 561 查看

邻接矩阵&最短路径&最小生成树

在对图的操作过程中,会有非常多灵活的操作,并且一个简单的操作会需要定义非常多的基础结构。下面是一个具有若干个主要功能的程序:图的邻接矩阵表示法,图的深度优先遍历,最小生成树的生成,最小路径的生成。此程序以邻接矩阵作为基础结构。

下面是相关的程序:

#include<stdio.h>
#define MAX 20
#define MAXINT 1000
typedef enum{
DG,DN,UDG,UDN
} GraphKind;

typedef struct ArcCell{   //权值
int distance;//用来表示两点间的权值
//InfoType * info;
}ArcCell ,AdjMatrix[MAX][MAX];

typedef struct {        //用来储存顶点向量
char points[MAX];//顶点向量
AdjMatrix arcs;   //用来表示邻接矩阵
int  vexnum,arcnum;//图当前定点数和弧数
GraphKind kind; //图的类型
}MGraph;

typedef struct Node{
char ch ;
int lowcost;
}Closedge[MAX]; //作为辅助数组,用来储存普里姆算法中分量值的变化

int find( char points[],int num,char ch){
int i;
for(i=0;i<num;i++){
if(points[i]==ch) return i;
}
}
void CreatUDN(MGraph &G){
int i,j,k,temp;
char ch1,ch2;
printf("请输入邻接矩阵的顶点数和弧数\n");
scanf("%d%d",&G.arcnum ,&G.vexnum );//输入临接矩阵的顶点数和弧数

for(i=0;i<G.arcnum;i++){
printf("请输入该顶点的信息\n");
fflush(stdin);
scanf("%c",&G.points[i]);
}

for(i=0;i<G.arcnum;i++)
for(j=0;j<G.arcnum;j++)
{
G.arcs[i][j].distance =MAXINT;
}

printf("请输入所有的弧的对应的顶点,和权值\n");

for(i=0;i<G.vexnum;i++)
{
fflush(stdin);
printf("请输入此弧对应的顶点和权值\n");
scanf("%c %c %d",&ch1,&ch2,&temp);
G.arcs[find(G.points,G.arcnum ,ch1)][find(G.points,G.arcnum ,ch2)].distance=temp;
}

}

void DFS(MGraph &G,int mark,int *p){
int i;

printf("\n顶点值%c\n",G.points[mark]);
p[mark]=1;
for(i=0;i<G.arcnum;i++)
{
if(G.arcs[mark][i].distance!=MAXINT&&p[i]!=1)
{
DFS(G,i,p);
}
}
}

void bianLi(MGraph G){     //深度优先遍历有
int ints[MAX];
int i;
for(i=0;i<G.arcnum ;i++)
ints[i]=0;
printf("按照深度优先遍历");
for(i=0;i<G.arcnum;i++){
if(ints[i]==0)DFS(G,i,ints);
}
}

int LocateVex(MGraph G,char u){
int i;
for(i=0;i<G.vexnum;i++){
if(G.points[i]==u)
return i;
}
}

int minimum( Closedge Fu,int length){
int min;

int i=0,mini=0;
for(i=0;i<length;i++)
if(Fu[i].lowcost!=0)
{  mini=i;
min=Fu[i].lowcost;break;
}

for(i=0;i<length;i++)
if(Fu[i].lowcost!=0){
mini=min<=Fu[i].lowcost?mini:i;
min=min<=Fu[i].lowcost?min:Fu[i].lowcost;
}

return mini;
}

void lestTree(MGraph G,char u){
Closedge Fu;          //作为辅助数组
int k=LocateVex(G,u);
int i,j;
for(j=0;j<G.arcnum;j++)
if(j!=k){
Fu[j].ch=u;
Fu[j].lowcost=G.arcs[k][j].distance;
}
Fu[k].ch=u;
Fu[k].lowcost=0;
for(i=0;i<G.arcnum-1;i++){
k=minimum(Fu,G.arcnum);//找到要新加入的节点下标

printf("\n下面是最小生成树的几条边\n输出生成树的边\n%c----------------%c",Fu[k].ch,G.points[k]);
Fu[k].lowcost=0;
for(j=0;j<G.arcnum;j++)
if(G.arcs[k][j].distance<Fu[j].lowcost){
Fu[j].ch=G.points[k];
Fu[j].lowcost= G.arcs[k][j].distance;
}
}
}

int minimumpoint( Closedge Fu,int length){
static int base=0;
int i,min=0,mini=0;
for(i=0;i<length;i++){
if(Fu[i].lowcost>base){
mini=i;
min=Fu[i].lowcost;
}
}
for(i=0;i<length;i++){
if(Fu[i].lowcost>base){
mini=Fu[mini].lowcost>Fu[i].lowcost?i:mini;
min=Fu[mini].lowcost>Fu[i].lowcost?Fu[i].lowcost:Fu[mini].lowcost;
}
}
base=min;
return mini;
}
void shortestRoute(MGraph G,char u){
Closedge Fu;          //作为辅助数组
int k=LocateVex(G,u);
int i,j;
for(j=0;j<G.arcnum;j++)
if(j!=k){
Fu[j].ch=u;
Fu[j].lowcost=G.arcs[k][j].distance;
}
Fu[k].ch=u;
Fu[k].lowcost=0;
for(i=0;i<G.arcnum-1;i++){
k=minimumpoint(Fu,G.arcnum);//找到要新加入的节点下标

printf("\n下面是最短路径的几条边\n输出生成树的边\n%c----------------%c",Fu[k].ch,G.points[k]);
//Fu[k].lowcost=0;
for(j=0;j<G.arcnum;j++)
if(G.arcs[k][j].distance+Fu[k].lowcost<Fu[j].lowcost){
Fu[j].ch=G.points[k];
Fu[j].lowcost= G.arcs[k][j].distance+Fu[k].lowcost;
}
}
}

int main(){
MGraph G;
CreatUDN(G);
bianLi(G);
char ch;
printf("\n请输入生成最小生成树开始的节点对应字母\n");
fflush(stdin);
lestTree(G,getchar());
printf("\n请输入生成最短生成路径开始的节点对应字母\n");
fflush(stdin);
shortestRoute(G,getchar());
return 0;
}


这个程序生成树和路径时用的表现手法是用线将俩接点相连,除此之外还有很多可以具体的地方。加油。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: