我是靠谱客的博主 动人小海豚,最近开发中收集的这篇文章主要介绍,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


//*******************************************引入头文件*********************************************
#include <stdio.h>
//使用了标准库函数 
#include <stdlib.h>
//使用了动态内存分配函数 
#include "SqQueue.cpp" //由于广度优先遍历要使用队列,而图中的顶点插入删除少访问多,故引入一个已写好的顺序队列 
//******************************************自定义符号常量*******************************************
#define OVERFLOW -2
//内存溢出错误常量
#define ILLEGAL -1
//非法操作错误常量 
#define OK 1
//表示操作正确的常量 
#define ERROR 0
//表示操作错误的常量
//******************************************自定义数据类型********************************************
typedef int Status;
//用typedef给int起个别名,也便于程序的维护
typedef float ElemType;
//用typedef给float起个别名,也便于程序的维护
//-------------图的数组(邻接矩阵)存储表示
#define INFINITY
65535
//最大值 ∞
#define MAX_VERTEX_NUM
20
//最大顶点个数
typedef enum {DG,DN,UDG,UDN} GraphKind;
//(有向图,有向网,无向图,无向网)
typedef int VRType;
typedef int VertexType;
typedef struct ArcCell{

VRType
adj;
//VRType是顶点关系类型。对无权图,用1或0,表示相邻与否,对带权图,则为权值类型 
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{

VertexType vexs[MAX_VERTEX_NUM];
//顶点向量

AdjMatrix
arcs;
//邻接矩阵

int vexnum,arcnum;
//图当前的定点数和弧数

GraphKind
kind;
//图的种类标志 
}MGraph;
//*********************************************图的主要操作********************************************
//------------------------------------1.图的创建(构造) ----------------------------------------------
int LocateVex(MGraph G, int v){
//顶点定位函数

for(int i=0; i<=G.vexnum; ++i)

if(G.vexs[i]==v)


return i;
//若找到结点返回i 

return -1;
//否则返回-1,表示没有找到 
}//LocateVex
/*说明:图变网,加权值,改距离
有向变无向 ,置邻接矩阵
反之也对

加权值
0,1变 ∞ 

有向图 <------------------------------> 有向网


|
去权值
∞变 0,1
| 

|
|

去对称矩阵
|
置对称矩阵
去对称矩阵
|
置对称矩阵

|
|

|
加权值
0,1变 ∞
|

无向图 <------------------------------> 无向网

去权值
∞变 0,1
*/
Status CreateUDN(MGraph &G){

//采用数组(邻接矩阵)表示法,构造无向网G

VertexType v1,v2;

int w,i,j;

printf("请依次输入无向网G的顶点数,弧数,用逗号隔开n");

scanf("%d,%d",&G.vexnum,&G.arcnum);

printf("请依次输入无向网G的顶点名称,用空格隔开n"); 

for(int i=0;i<G.vexnum;++i)

scanf("%d",&G.vexs[i]);
//构造各顶点向量 

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)

G.arcs[i][j].adj=INFINITY; 

printf("请依次输入无向网G每条弧依附的两顶点名称及权值,输完一组按回车n"); 

for(int k=0;k<G.arcnum;++k){ //构造邻接矩阵 

scanf("%d",&v1);

scanf("%d",&v2);

scanf("%d",&w); 

i=LocateVex(G,v1);

j=LocateVex(G,v2);
//确定v1,v2在G中的位置 

G.arcs[i][j].adj=w;

G.arcs[j][i]=G.arcs[i][j];
//置<v1,v2>的对称弧<v2,v1> 

}//for

return OK; 
}// CreateUDN
Status CreateUDG(MGraph &G){

//采用数组(邻接矩阵)表示法,构造无向图G 

VertexType v1,v2;

int i,j;

printf("请依次输入无向图G的顶点数,弧数,用逗号隔开n");

scanf("%d,%d",&G.vexnum,&G.arcnum);

printf("请依次输入无向图G的顶点名称,用空格隔开n"); 

for(int i=0;i<G.vexnum;++i)

scanf("%d",&G.vexs[i]);
//构造各顶点向量 

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)
//预置邻接矩阵 

G.arcs[i][j].adj=0; 

printf("请依次输入无向图G每条弧依附的两顶点名称,输完一组按回车n"); 

for(int k=0;k<G.arcnum;++k){ //构造邻接矩阵 

scanf("%d",&v1);

scanf("%d",&v2);

i=LocateVex(G,v1);

j=LocateVex(G,v2);
//确定v1,v2在G中的位置 

G.arcs[i][j].adj=1;

G.arcs[j][i]=G.arcs[i][j];
//置<v1,v2>的对称弧<v2,v1> 

}//for

return OK; 
}// CreateUDG
Status CreateDN(MGraph &G){

//采用数组(邻接矩阵)表示法,构造有向网G 

VertexType v1,v2;

int w,i,j;

printf("请依次输入有向网G的顶点数,弧数,用逗号隔开n");

scanf("%d,%d",&G.vexnum,&G.arcnum);

printf("请依次输入有向网G的顶点名称,用空格隔开n"); 

for(int i=0;i<G.vexnum;++i)

scanf("%d",&G.vexs[i]);
//构造各顶点向量 

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)

G.arcs[i][j].adj=INFINITY;


printf("请依次输入有向网G每条弧依附的两顶点名称及权值,输完一组按回车n"); 

for(int k=0;k<G.arcnum;++k){ //构造邻接矩阵 

scanf("%d",&v1);

scanf("%d",&v2);

scanf("%d",&w); 

i=LocateVex(G,v1);

j=LocateVex(G,v2);
//确定v1,v2在G中的位置 

G.arcs[i][j].adj=w;

}//for

return OK; 
}// CreateDN
Status CreateDG(MGraph &G){

//采用数组(邻接矩阵)表示法,构造有向图G 

VertexType v1,v2;

int i,j;

printf("请依次输入有向图G的顶点数,弧数,用逗号隔开n");

scanf("%d,%d",&G.vexnum,&G.arcnum);

printf("请依次输入有向图G的顶点名称,用空格隔开n"); 

for(int i=0;i<G.vexnum;++i)

scanf("%d",&G.vexs[i]);
//构造各顶点向量 

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)

G.arcs[i][j].adj=0; 

printf("请依次输入有向图G每条弧依附的两顶点名称,输完一组按回车n"); 

for(int k=0;k<G.arcnum;++k){ //构造邻接矩阵 

scanf("%d",&v1);

scanf("%d",&v2);

i=LocateVex(G,v1);

j=LocateVex(G,v2);
//确定v1,v2在G中的位置 

G.arcs[i][j].adj=1;

}//for

return OK; 
}// CreateDG
Status CreateGraph(MGraph &G){
//总函数

//采用数组(邻接矩阵)表示法,构造图G

printf("请输入您想构造的图的类型:有向图,有向网,无向图,无向网,分别对应0,1,2,3):");

int temp; 

scanf("%d",&temp);
//输入所要构造图的类型

G.kind=(GraphKind)temp;

switch((GraphKind)temp){

case
DG:
return CreateDG(G);
//构造有向图G

case
DN:
return CreateDN(G);
//构造有向网G

case UDG:
return CreateUDG(G); //构造无向图G

case UDN:
return CreateUDN(G); //构造无向网G

default :
return ERROR;

} 
}//CreateGraph
//---------------------------------2.邻接矩阵的输出 ----------------------------------------------
Status PrintAdjMatrix(MGraph G){
//打印某个图的邻接矩阵

//采用数组(邻接矩阵)表示法,构造图G

for(int i=0;i<G.vexnum;i++){

for(int j=0;j<G.vexnum;j++)

if(G.arcs[i][j].adj==INFINITY)


printf("
∞ ");

else 

printf(" %3d ", G.arcs[i][j].adj);

printf("nn");

}

}//PrintAdjMatrix
//------------------------------------3.图的遍历 ----------------------------------------------
int FirstAdjVex(MGraph G,VertexType v){

//求顶点v在图G中的第一个邻接点

int i,j=0,k;

k=LocateVex(G,v);
//v是顶点,不是序号!需要定位 

if(G.kind==DN||G.kind==UDN)
//若是网

j=INFINITY;

for(i=0;i<G.vexnum;++i)

if(G.arcs[k][i].adj!=j)

return i;
//若找到则返回i 

return -1;
//若未找到返回-1 
}//FirstAdjVex
int NextAdjVex(MGraph G,VertexType v,VertexType w){

//求顶点v在图G中相对于邻接点w的下一个邻接点 

int i,j=0,k1,k2;

k1=LocateVex(G,v);
//v是顶点,不是序号!需要定位


k2=LocateVex(G,w);
//w是顶点,不是序号!需要定位 

if(G.kind==DN||G.kind==UDN)
//若是网

j=INFINITY;

for(i=k2+1;i<G.vexnum;++i)

if(G.arcs[k1][i].adj!=j)

return i;
//若找到则返回i 

return -1;
//若未找到返回-1

}//NextAdjVex
//-----------------------深度优先遍历DFS-----------------------------
typedef enum { TRUE=1 , FALSE=0 } Boolean;
Boolean visited[MAX_VERTEX_NUM];
//访问标志数组
Status (*VisitFunc)(int v);
//函数变量
Status Print(int v){
//元素访问函数

printf(" %3d ",v);

return OK;
}//Print
void DFSTraverse(MGraph G,Status (*Visit)(int v)){

//对图G作深度优先遍历,调用Visit()函数访问结点

void DFS(MGraph G,int v);
//函数声明 

VisitFunc=Visit;
//使用全局变量VisitFunc,使DFS不必设函数指针参数 

for(int v=0;v<G.vexnum;++v)

visited[v]=FALSE;
//预置标志数组

for(int v=0;v<G.vexnum;++v)

if(!visited[v])
//若该顶点未被访问 

DFS(G,v); 
}//DFSTraverse
void DFS(MGraph G,int v){

//从第v个顶点出发递归地深度优先遍历图G

visited[v]=TRUE;
//先将访问标志数组该元素的访问标志改为True 

//注意,序号v从0开始,所以序号v总比第v个顶点在图中的位置少1 

VisitFunc(G.vexs[v]);
//访问第v个顶点
注意:v是序号,不是顶点! 

for(int w=FirstAdjVex(G,G.vexs[v]);w>=0;w=NextAdjVex(G,G.vexs[v],G.vexs[w])){
//v是序号,不是顶点!

if(!visited[w])

DFS(G,w);
//对v的尚未访问的邻接点w递归调用DFS 

}//for
}//DFS
//----------------广度优先遍历 (需要使用队列)BFS------------
//说明:队列的相关代码包含在"SqQueue.cpp"中,关于队列的详细方法请阅读该文件
void BFSTraverse(MGraph G,Status (*Visit)(int v)){

//按广度优先非递归遍历图G,使用辅助队列Q和访问标志数组visited

SqQueue Q; 

for(int v=0;v<G.vexnum;++v)

visited[v]=FALSE;
//预置标志数组

InitQueue_Sq(Q);
//置空辅助队列Q

for(int v=0;v<G.vexnum;++v)

if(!visited[v]){
//v尚未访问 

visited[v]=TRUE;


Visit(G.vexs[v]);
//访问第v顶点

EnQueue_Sq(Q,v);
//v入队列 

while(!QueueEmpty_Sq(Q)){
//队列不空 

DeQueue_Sq(Q,v);
//队头元素出队并置为u

for(int w=FirstAdjVex(G,G.vexs[v]);w>=0;w=NextAdjVex(G,G.vexs[v],G.vexs[w])){ 

if(!visited[w]){
//w为v尚未访问的邻接顶点 

visited[w]=TRUE;


Visit(G.vexs[w]);
//访问第w顶点 

}//if 

}//for 

}//while 

}//if
}//BFSTraverse
//------------------------------------ 4.最小生成树 ----------------------------------------------
//-------------------辅助数组的定义-------------------------------
struct Record{

VertexType adjvex;
//顶点 

VRType
lowcost;
//最低代价 
}closedge[MAX_VERTEX_NUM];
int minimum(Record closedge[]){

int reserve=65535,min;

for(int i=1;i<MAX_VERTEX_NUM;i++)

if(closedge[i].lowcost<reserve&&closedge[i].lowcost>0){
//没有访问过但是存在路径

reserve=closedge[i].lowcost;

min=i;

}//if

return min;
}//minimum
void MiniSpanTree_PRIM(MGraph G,VertexType u){
//普里姆算法求最小生成树

//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边

//记录从定点集U到V-U的代价最小的边的辅助数组定义

int k=LocateVex(G,u);

for(int j=0;j<G.vexnum;++j)
//辅助数组初始化

if(j!=k){

closedge[j].adjvex=u;

closedge[j].lowcost=G.arcs[k][j].adj;
//{adjvex, lowcost}

}//if

closedge[k].lowcost=0;
//初始,U={u} 

printf("最小生成树各条边:n顶点
权值
顶点
n");


for(int i=1;i<G.vexnum;++i){

k=minimum(closedge);
//求出T的下一个结点:第k顶点

//此时closedge[k].lowcost= MIN{ closedge[vi].lowcost | closedge[vi].lowcost>0, vi ∈V-U} 

printf(" %2d <--- %2d ---> %2d n",closedge[k].adjvex,closedge[k].lowcost,G.vexs[k]);
//输出生成树的边及其权值 

closedge[k].lowcost = 0;
//第k顶点并入U集

for(int j=1;j<G.vexnum;++j)

if(G.arcs[k][j].adj < closedge[j].lowcost){
//新顶点并入U后重新选择最小边(更新最小边信息)

closedge[j].adjvex=G.vexs[k];

closedge[j].lowcost=G.arcs[k][j].adj; 

}//if

}//for

}//MiniSpanTree_PRIM
//------------------------------------ 5.最短路径 ----------------------------------------------
//---------------------------迪斯特拉算法辅助数组的定义--------------------------------
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
void ShortestPath_DIJ(MGraph G,int v0,PathMatrix &P,ShortPathTable &D){
//用迪斯特拉算法求有向图G最短路径

//用Dijkstra算法求有向图G的顶点v0顶点到其余顶点v的最短路径P[v]及其带权长度D[v]

//若P[v][w]为TRUE,则w是从v0到v当前求得最小路径上的顶点

//final[v]为TRUE当且仅当v∈S,即已经求得v0到v的最短路径

int i,v,w,j,min;

Status final[MAX_VERTEX_NUM];

for(v=0;v<G.vexnum;++v){

final[v]=FALSE;

D[v]=G.arcs[v0][v].adj;

for(w=0;w<G.vexnum;++w)

P[v][w]=FALSE;
//设空路径 

if(D[v]<INFINITY){

P[v][v0]=TRUE;

P[v][w]=TRUE;

}//if


}//for

D[v0]=0;

final[v0]=TRUE;
//初始化,v0顶点属于S集

//开始主循环,每次求得v0到某个顶点v的最短路径,并加v到S集 

for(i=0;i<G.vexnum;++i){
//其余G.vexnum-1个顶点 

min=INFINITY;
//当前所知离v0顶点最近距离

for(w=0;w<G.vexnum;++w)

if(!final[w])
//w顶点在V-S中 

if(D[w]<min){

v=w;
//w顶点离v0顶点更近 

min=D[w];

}//if 

final[v]=TRUE;
//离v0顶点最近的v加入S集

for(w=0;w<G.vexnum;++w)
//更新当前最短路径及距离

if(!final[w]&&(min+G.arcs[v][w].adj<D[w])){
//修改D[w]和P[w],w∈V-S 

D[w]=min+G.arcs[v][w].adj;

for(j=0;j<G.vexnum;++j)

P[w][j]=P[v][j];

P[w][w]=TRUE;
//P[w]=P[v]+[w]

}//if 

}//for

}//ShortestPath_DIJ
//---------------------------弗洛伊德算法辅助数组的定义--------------------------------
typedef int PathMatrix1[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int DistanceMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
void ShortestPath_FLOYD(MGraph G,PathMatrix1 &P,DistanceMatrix &D){
//用弗洛伊德算法求有向网G最短路径

//用Floyd算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]。

//若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点。

int v,w,u,i; 

for(v=0;v<G.vexnum;++v)
//各对结点之间的初始已知路径及距离 

for(w=0;w<G.vexnum;++w){

D[v][w]=G.arcs[v][w].adj;

for(u=0;u<G.vexnum;++u)

P[v][w][u]=FALSE;

if(D[v][w]<INFINITY){
//从v到w有直接路径 

P[v][w][v]=TRUE;

P[v][w][w]=TRUE; 

}//if 

}//for

for(u=0;u<G.vexnum;++u)

for(v=0;v<G.vexnum;++v)

for(w=0;w<G.vexnum;++w)

if(D[v][u]+D[u][v]<D[v][w]){
//从v经u到w的一条路径更短 

D[v][w]=D[v][u]+D[u][w];

for(i=0;i<G.vexnum;++i)

P[v][w][i]=P[v][u][i]||P[u][w][i]; 

}//if 
}//ShortestPath_FLOYD
//-------------------------------主函数-------------------------------
int main(int argc,char *argv[]){

printf("n---------------------------------图的邻接矩阵表示-------------------------------n"); 

MGraph G; 

printf("
----------------------图的建立------------------
n");

CreateGraph(G);
//图的创建

printf("
--------------------图的邻接矩阵----------------
nn"); 

PrintAdjMatrix(G);
//打印邻接矩阵 

printf("
----------------------图的遍历------------------
n");

printf("深度优先遍历结果:");

DFSTraverse(G,Print);

printf("n广度优先遍历结果:");

BFSTraverse(G,Print);

printf("n");

if(G.kind==UDN){
//若为无向网,求其最小生成树 

printf("
-----------------无向网的最小生成树-------------
n");

MiniSpanTree_PRIM(G,G.vexs[0]); 

}//if

int v0=0;
//源点


PathMatrix P;

PathMatrix1 P1;

ShortPathTable D;

DistanceMatrix D1; 

if(G.kind==DN){ 

printf("
------------------有向网的最短路径--------------
n");

printf("ttt执行迪斯特拉算法:n"); 

ShortestPath_DIJ(G,v0,P,D);

printf("最短路径数组P[i][j]如下:n");

for(int i=0;i<G.vexnum;++i){

for(int j=0;j<G.vexnum;++j)

printf(" %3d ",P[i][j]);

printf("n");

}//for

printf("顶点%d到其他顶点的最短路径如下:n",v0);

for(int i=0;i<G.vexnum;++i)

printf("%d--->%d :%3dn",v0,G.vexs[i],D[i]);

printf("ttt执行弗洛伊德算法:n");

for(int i=0;i<G.vexnum;++i)

G.arcs[i][i].adj=0;
//ShortestPath_FLOYD()要求对角线元素为0 

printf("执行算法前的邻接矩阵如下:n");

PrintAdjMatrix(G);

ShortestPath_FLOYD(G,P1,D1);

printf("DistanceMatrix矩阵:n");

for(int i=0;i<G.vexnum;++i){

for(int j=0;j<G.vexnum;++j){

if(D1[i][j])

printf("
∞ ");

else

printf(" %5d ",D1[i][j]);

}//for


printf("nn");

}//for

printf("n最短路径的计算结果:n");

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)

printf("%d--->%d 最短路径:%dn",G.vexs[i],G.vexs[j],D1[i][j]);


printf("n最短路径数组P[i][j][k]如下:n");

for(int i=0;i<G.vexnum;++i)

for(int j=0;j<G.vexnum;++j)

for(int k=0;k<G.vexnum;++k){

printf("P[%d][%d][%d]=%d
",i,j,k,P1[i][j][k]);

if((k+1)%3==0)

printf("n");

}//for

}//if 

return 0;
}
/*--------------------------输入全程记录(便于测试,可直接复制)------------------------------
说明:下面输入的无向图来自教材P174页,可以直接去该页寻找最小生成树正确结果,以便于验证算法正确与否
---------------------------------图的邻接矩阵表示-------------------------------

----------------------图的建立------------------
请输入您想构造的图的类型:有向图,有向网,无向图,无向网,分别对应0,1,2,3):3
请依次输入无向网G的顶点数,弧数,用逗号隔开
6,10
请依次输入无向网G的顶点名称,用空格隔开
1 2 3 4 5 6
请依次输入无向网G每条弧依附的两顶点名称及权值,输完一组按回车
1 2 6
1 4 5
1 3 1
3 2 5
3 4 5
3 5 6
3 6 4
2 5 3
4 6 2
5 6 6

--------------------图的邻接矩阵----------------
∞
6
1
5
∞
∞
6
∞
5
∞
3
∞
1
5
∞
5
6
4
5
∞
5
∞
∞
2
∞
3
6
∞
∞
6
∞
∞
4
2
6
∞

----------------------图的遍历------------------
深度优先遍历结果:
1
2
3
4
6
5
广度优先遍历结果:
1
2
3
4
5
6

-----------------无向网的最小生成树-------------
最小生成树各条边:
顶点
权值
顶点
1 <---
1 --->
3
3 <---
4 --->
6
6 <---
2 --->
4
3 <---
5 --->
2
2 <---
3 --->
5
--------------------------------
Process exited with return value 0
Press any key to continue . . .
说明:下面输入的无向图来自教材P188页,可以直接去该页寻找最短路径的正确结果,以便于验证算法正确与否
---------------------------------图的邻接矩阵表示-------------------------------

----------------------图的建立------------------
请输入您想构造的图的类型:有向图,有向网,无向图,无向网,分别对应0,1,2,3):1
请依次输入有向网G的顶点数,弧数,用逗号隔开
6,8
请依次输入有向网G的顶点名称,用空格隔开
0 1 2 3 4 5
请依次输入有向网G每条弧依附的两顶点名称及权值,输完一组按回车
0 5 100
0 4 30
0 2 10
1 2 5
2 3 50
4 3 20
4 5 60
3 5 10

--------------------图的邻接矩阵----------------
∞
∞
10
∞
30
100
∞
∞
5
∞
∞
∞
∞
∞
∞
50
∞
∞
∞
∞
∞
∞
∞
10
∞
∞
∞
20
∞
60
∞
∞
∞
∞
∞
∞

----------------------图的遍历------------------
深度优先遍历结果:
0
2
3
5
4
1
广度优先遍历结果:
0
2
4
5
1
3

------------------有向网的最短路径--------------

执行迪斯特拉算法:
最短路径数组P[i][j]如下:
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
1
0
0
1
0
0
1
0
0
0
0
0
1
0
0
1
0
1
顶点0到其他顶点的最短路径如下:
0--->0 :
0
0--->1 :65535
0--->2 : 10
0--->3 : 50
0--->4 : 30
0--->5 : 60

执行弗洛伊德算法:
执行算法前的邻接矩阵如下:
0
∞
10
∞
30
100
∞
0
5
∞
∞
∞
∞
∞
0
50
∞
∞
∞
∞
∞
0
∞
10
∞
∞
∞
20
0
60
∞
∞
∞
∞
∞
0
DistanceMatrix矩阵:
0
∞
∞
∞
∞
∞
∞
0
∞
∞
∞
∞
∞
∞
0
∞
∞
∞
∞
∞
∞
0
∞
∞
∞
∞
∞
∞
0
∞
∞
∞
∞
∞
∞
0
最短路径的计算结果:
0--->0 最短路径:0
0--->1 最短路径:65535
0--->2 最短路径:10
0--->3 最短路径:65535
0--->4 最短路径:30
0--->5 最短路径:100
1--->0 最短路径:65535
1--->1 最短路径:0
1--->2 最短路径:5
1--->3 最短路径:65535
1--->4 最短路径:65535
1--->5 最短路径:65535
2--->0 最短路径:65535
2--->1 最短路径:65535
2--->2 最短路径:0
2--->3 最短路径:50
2--->4 最短路径:65535
2--->5 最短路径:65535
3--->0 最短路径:65535
3--->1 最短路径:65535
3--->2 最短路径:65535
3--->3 最短路径:0
3--->4 最短路径:65535
3--->5 最短路径:10
4--->0 最短路径:65535
4--->1 最短路径:65535
4--->2 最短路径:65535
4--->3 最短路径:20
4--->4 最短路径:0
4--->5 最短路径:60
5--->0 最短路径:65535
5--->1 最短路径:65535
5--->2 最短路径:65535
5--->3 最短路径:65535
5--->4 最短路径:65535
5--->5 最短路径:0
最短路径数组P[i][j][k]如下:
P[0][0][0]=1
P[0][0][1]=0
P[0][0][2]=0
P[0][0][3]=0
P[0][0][4]=0
P[0][0][5]=0
P[0][1][0]=1
P[0][1][1]=0
P[0][1][2]=0
P[0][1][3]=0
P[0][1][4]=0
P[0][1][5]=0
P[0][2][0]=1
P[0][2][1]=0
P[0][2][2]=1
P[0][2][3]=0
P[0][2][4]=0
P[0][2][5]=0
P[0][3][0]=1
P[0][3][1]=0
P[0][3][2]=0
P[0][3][3]=0
P[0][3][4]=0
P[0][3][5]=0
P[0][4][0]=1
P[0][4][1]=0
P[0][4][2]=0
P[0][4][3]=0
P[0][4][4]=1
P[0][4][5]=0
P[0][5][0]=1
P[0][5][1]=0
P[0][5][2]=0
P[0][5][3]=0
P[0][5][4]=0
P[0][5][5]=1
P[1][0][0]=0
P[1][0][1]=1
P[1][0][2]=0
P[1][0][3]=0
P[1][0][4]=0
P[1][0][5]=0
P[1][1][0]=0
P[1][1][1]=1
P[1][1][2]=0
P[1][1][3]=0
P[1][1][4]=0
P[1][1][5]=0
P[1][2][0]=0
P[1][2][1]=1
P[1][2][2]=1
P[1][2][3]=0
P[1][2][4]=0
P[1][2][5]=0
P[1][3][0]=0
P[1][3][1]=1
P[1][3][2]=0
P[1][3][3]=0
P[1][3][4]=0
P[1][3][5]=0
P[1][4][0]=0
P[1][4][1]=1
P[1][4][2]=0
P[1][4][3]=0
P[1][4][4]=0
P[1][4][5]=0
P[1][5][0]=0
P[1][5][1]=1
P[1][5][2]=0
P[1][5][3]=0
P[1][5][4]=0
P[1][5][5]=0
P[2][0][0]=0
P[2][0][1]=0
P[2][0][2]=1
P[2][0][3]=0
P[2][0][4]=0
P[2][0][5]=0
P[2][1][0]=0
P[2][1][1]=0
P[2][1][2]=1
P[2][1][3]=0
P[2][1][4]=0
P[2][1][5]=0
P[2][2][0]=0
P[2][2][1]=0
P[2][2][2]=1
P[2][2][3]=0
P[2][2][4]=0
P[2][2][5]=0
P[2][3][0]=0
P[2][3][1]=0
P[2][3][2]=1
P[2][3][3]=1
P[2][3][4]=0
P[2][3][5]=0
P[2][4][0]=0
P[2][4][1]=0
P[2][4][2]=1
P[2][4][3]=0
P[2][4][4]=0
P[2][4][5]=0
P[2][5][0]=0
P[2][5][1]=0
P[2][5][2]=1
P[2][5][3]=0
P[2][5][4]=0
P[2][5][5]=0
P[3][0][0]=0
P[3][0][1]=0
P[3][0][2]=0
P[3][0][3]=1
P[3][0][4]=0
P[3][0][5]=0
P[3][1][0]=0
P[3][1][1]=0
P[3][1][2]=0
P[3][1][3]=1
P[3][1][4]=0
P[3][1][5]=0
P[3][2][0]=0
P[3][2][1]=0
P[3][2][2]=0
P[3][2][3]=1
P[3][2][4]=0
P[3][2][5]=0
P[3][3][0]=0
P[3][3][1]=0
P[3][3][2]=0
P[3][3][3]=1
P[3][3][4]=0
P[3][3][5]=0
P[3][4][0]=0
P[3][4][1]=0
P[3][4][2]=0
P[3][4][3]=1
P[3][4][4]=0
P[3][4][5]=0
P[3][5][0]=0
P[3][5][1]=0
P[3][5][2]=0
P[3][5][3]=1
P[3][5][4]=0
P[3][5][5]=1
P[4][0][0]=0
P[4][0][1]=0
P[4][0][2]=0
P[4][0][3]=0
P[4][0][4]=1
P[4][0][5]=0
P[4][1][0]=0
P[4][1][1]=0
P[4][1][2]=0
P[4][1][3]=0
P[4][1][4]=1
P[4][1][5]=0
P[4][2][0]=0
P[4][2][1]=0
P[4][2][2]=0
P[4][2][3]=0
P[4][2][4]=1
P[4][2][5]=0
P[4][3][0]=0
P[4][3][1]=0
P[4][3][2]=0
P[4][3][3]=1
P[4][3][4]=1
P[4][3][5]=0
P[4][4][0]=0
P[4][4][1]=0
P[4][4][2]=0
P[4][4][3]=0
P[4][4][4]=1
P[4][4][5]=0
P[4][5][0]=0
P[4][5][1]=0
P[4][5][2]=0
P[4][5][3]=0
P[4][5][4]=1
P[4][5][5]=1
P[5][0][0]=0
P[5][0][1]=0
P[5][0][2]=0
P[5][0][3]=0
P[5][0][4]=0
P[5][0][5]=1
P[5][1][0]=0
P[5][1][1]=0
P[5][1][2]=0
P[5][1][3]=0
P[5][1][4]=0
P[5][1][5]=1
P[5][2][0]=0
P[5][2][1]=0
P[5][2][2]=0
P[5][2][3]=0
P[5][2][4]=0
P[5][2][5]=1
P[5][3][0]=0
P[5][3][1]=0
P[5][3][2]=0
P[5][3][3]=0
P[5][3][4]=0
P[5][3][5]=1
P[5][4][0]=0
P[5][4][1]=0
P[5][4][2]=0
P[5][4][3]=0
P[5][4][4]=0
P[5][4][5]=1
P[5][5][0]=0
P[5][5][1]=0
P[5][5][2]=0
P[5][5][3]=0
P[5][5][4]=0
P[5][5][5]=1
--------------------------------
Process exited with return value 0
Press any key to continue . . .
*/

2.0

#include <stdio.h>
#include <stdlib.h>
#define MAX_VEX_NUM 20
#define INFINITY -1
// 顶点访问标志类型声明 
typedef enum {UNVISITED=0, VISITED=1} visit_t;
// 采用邻接矩阵表示法的图类型定义 
// 这里假设:顶点的信息为 unsigned int类型;边的信息 也为 unsigned int类型, 1表示有边, 0 表示无边。 
typedef struct
{
unsigned int vertex[MAX_VEX_NUM];
unsigned int arcs[MAX_VEX_NUM][MAX_VEX_NUM];
int vex_num, arc_num;
} m_graph_t;
// 输出图的邻接矩阵 
void print_graph(m_graph_t g)
{
int i, j;
for (i=0; i<g.vex_num; i++) {
for (j=0; j<g.vex_num; j++)
printf("%3d", g.arcs[i][j]);
printf("n");
}
}
// 求图g中顶点v的第一个邻接点,若存在,则返回该邻接点在图中的位置(>=0);否则返回-1。 
int first_adj(m_graph_t g, int v)
{
int w = 0;
while ((w<g.vex_num) && (g.arcs[v][w]==0)) w++;
if (w==g.vex_num) return -1;
else return w;
}
// 求图g中顶点v的相对于邻接点w的下一个邻接点,若存在,则返回该邻接点在图中的位置(>=0);否则返回-1。 
int next_adj(m_graph_t g, int v, int w)
{
int u = w+1;
while ((u<g.vex_num) && (g.arcs[v][u]==0)) u++;
if (u==g.vex_num) return -1;
else return u;
}
// 深度优先搜索遍历 
visit_t visited[MAX_VEX_NUM];
void depth_first(m_graph_t g, int v)
{
int w;
visited[v] = VISITED;
printf("%3d",g.vertex[v]);
for (w=first_adj(g, v); w >= 0; w=next_adj(g, v, w))
if (!visited[w]) depth_first(g, w);
}
void depth_first_traverse(m_graph_t g)
{
int v;
for (v=0;v<g.vex_num;v++) visited[v] = UNVISITED;
for (v=0;v<g.vex_num;v++)
if (!visited[v]) depth_first(g, v);
}
// 队列的存储结构及基本操作 
typedef unsigned int queue_elem_t;
// typedef int queue_elem_t;
typedef enum {EMPTY, FULL, READY} status_t;
typedef struct
{
queue_elem_t *data;
int front;
int rear;
int queue_len;
status_t status;
} queue;
typedef queue *queue_t;
queue_t init_queue(int len)
{
queue_t q = (queue_t)malloc(sizeof(queue));
if (!q) {
printf("Heap full.n");
exit(-1);
}
q->data = (queue_elem_t *)malloc(sizeof(queue_elem_t) * len);
if (!q->data) {
printf("Heap full.n");
exit(-1);
}
q->front = q->rear = 0;
q->queue_len = len;
q->status = EMPTY;
return q;
}
queue_t destroy_queue(queue_t q)
{
if (q) {
free(q->data);
free(q);
}
return NULL;
}
int is_empty(queue_t q)
{
return (q->status==EMPTY);
}
void enqueue(queue_t q, queue_elem_t data)
{
if (!q) {
printf("You need init queue before using it.n");
exit(-1);
}
if (q->status != FULL) {
q->data[q->rear] = data;
q->rear = (q->rear + 1) % q->queue_len;
if (q->rear == q->front)
q->status = FULL;
else
q->status = READY;
}
}
queue_elem_t dequeue(queue_t q)
{
queue_elem_t data;
if (!q) {
printf("You need init queue before using it.n");
exit(-1);
}
if (q->status != EMPTY) {
data = q->data[q->front];
q->front = (q->front + 1) % q->queue_len;
if (q->front == q->rear)
q->status = EMPTY;
else
q->status = READY;
}
return data;
}
queue_elem_t get_front(queue_t q)
{
return q->data[q->front];
}
void visit_front(queue_t q, void (*do_front)(queue_elem_t *))
{
if (q->status != EMPTY)
do_front(&(q->data[q->front]));
}
void traverse_queue(queue_t q, void (*do_data)(queue_elem_t *))
{
int front;
if (q->status != EMPTY) {
front = q->front;
do {
do_data(&(q->data[front]));
front = (front + 1) % q->queue_len;
} while (front != q->rear);
}
}
// 广度优先搜索遍历 
void breadth_first_traverse(m_graph_t g)
{
visit_t visited[MAX_VEX_NUM];
int u, v, w;
queue_t q = init_queue(g.vex_num);
for (v=0;v<g.vex_num;v++) visited[v] = UNVISITED;
for (v=0;v<g.vex_num;v++)
if (!visited[v]) {
visited[v] = VISITED;
printf("%3d", g.vertex[v]);
enqueue(q, v);
while (!is_empty(q)) {
u = dequeue(q);
for (w=first_adj(g, u); w!=-1; w=next_adj(g, u, w))
if (!visited[w]) {
visited[w] = VISITED;
printf("%3d", g.vertex[w]);
enqueue(q, w);
} //if 
} // while
} // if
destroy_queue(q);
}
// 顶点定位函数 
int LocateVex(m_graph_t *g, unsigned int v){
int i;
for (i = 0; i <= g->vex_num; ++i){
if(g->vertex[i]==v) return i;
}
return -1;
}
// 无向图构造函数 
void create_UDG(m_graph_t *g)
{ //采用数组(邻接矩阵)表示法,构造无向网g。
int i, j, k;
unsigned int v1, v2;
printf("请输入图的顶点数和边数:");
scanf("%d,%d", &g->vex_num, &g->arc_num);
printf("请输入%d个顶点的信息:n", g->vex_num);
for (i = 0; i < g->vex_num; ++i) scanf("%d", &g->vertex[i]); //构造顶点向量
for (i = 0; i < g->vex_num; ++i) //初始化邻接矩阵
for (j = 0; j < g->vex_num; ++j) g->arcs[i][j] = 0;
printf("请输入%d条边的信息:", g->arc_num);
for (k = 0; k < g->arc_num; ++k) { //构造邻接矩阵
printf("n第%d条边(输入该边所依附的两个顶点):", k+1);
scanf("%d,%d",&v1, &v2);
//输入一条边依附的顶点
i = LocateVex(g, v1); j = LocateVex(g, v2); //确定v1和v2在G中位置
g->arcs[i][j] = 1;
g->arcs[j][i] = g->arcs[i][j]; //置<v1, v2>的对称边<v2, v1>
}
return;
}
/*
1
/ 
/

2
3
/ 
/ 
4
5 6---7
 /
8
*/
int main()
{
/*
m_graph_t g = {
{1, 2, 3, 4, 5, 6, 7, 8}, // vertex
{{
0,
1,
1,
0,
0,
0,
0,
0}, // arcs
{
1,
0,
0,
1,
1,
0,
0,
0},
{
1,
0,
0,
0,
0,
1,
1,
0},
{
0,
1,
0,
0,
0,
0,
0,
1},
{
0,
1,
0,
0,
0,
0,
0,
1},
{
0,
0,
1,
0,
0,
0,
1,
0},
{
0,
0,
1,
0,
0,
1,
0,
0},
{
0,
0,
0,
1,
1,
0,
0,
0}},
8, // vex_num
9 // arc_num
};
*/
m_graph_t g;
create_UDG(&g);
// 调用创建无向图的函数 
print_graph(g); printf("n");
depth_first_traverse(g); printf("n");
breadth_first_traverse(g); printf("n");
return 0;
}

最后

以上就是动人小海豚为你收集整理的的全部内容,希望文章能够帮你解决所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部