当前位置:文档之家› Graph 图(数据结构) 及IO实例

Graph 图(数据结构) 及IO实例

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define OVERFLOW -2

#define NULL 0

typedef int Status;

#include

#include

#include

/*-------------------*/

/***以下是"图"相关定义***/

typedef char VertexType;

//本程序选用ASCII字符区分各顶点#define IOTYPE "%c"

//VertexType的输入输出格式

#define MAX_VER_NUM 19

//最大支持的顶点数,说明见下#define NOTFOUND MAX_VER_NUM+1

//找不到顶点位置时的返回值

#define INFINITY 1000

//"无穷大" ∞

typedef unsigned VRType,AdjMatrix[MAX_VER_NUM][MAX_VER_NUM]; //带权的弧(Arc),以及邻接矩阵类型定义

//以unsigned类型存放权值,但DOS字符界面下横排仅有80个字符宽

//为了完整的显示邻接矩阵,权值不能超过三位数,顶点数不能超过19 typedef enum{DG,DN,UDG,UDN} GraphKind; //标明"图"种类的枚举型变量

typedef struct

{VertexType vexs[MAX_VER_NUM]; //顶点信息数组

AdjMatrix arcs; //邻接矩阵

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

GraphKind kind;} //图的种类

MGraph; //邻接矩阵表示的"图"之结构体

typedef Status PathMatrix[MAX_VER_NUM][MAX_VER_NUM];

//用于存放"最短路径上的顶点标记"的矩阵类型定义

typedef unsigned ShortPathTable[MAX_VER_NUM];

//用于存放"各顶点的最短路径长度"的数组类型定义

/*

C++/C 中的数组下标从零开始,而数据结构中经常不用零号位!

例如本程序中的MGraph.vexs[ ]数组(存放顶点信息)用零号位,

但visited[ ](存放顶点的访问标记)数组不用.

为了方便起见,也为了区分清楚,特以i/j 表示数组下标(从0开始);

以u/v/w/n 表示顶点编号(从1开始)--在visited[ ]数组中

同时也是数组下标,因为不使用零号位.

另外如head等指针在进行加减或比较运算时的标准同"下标".

*/

unsigned LocateVex(MGraph G,VertexType v); //在图G中查找值为v的顶点,并返回其位置

unsigned FirstAdjVex(MGraph G,unsigned n); //返回编号为n顶点的第一个邻接顶点unsigned NextAdjVex(MGraph G,unsigned n,unsigned adj);

//返回编号为n顶点的,相对其邻接顶点adj的下一个邻接顶点

void CreateGraph(MGraph &G,GraphKind kind); //采用邻接矩阵表示法,构造kind类型的图G

void ShowGraph(MGraph G); //显示图G的所有信息

void DFS(MGraph G,unsigned v); //从第v个顶点出发,深度优先遍历图G。

void DFSTraverse(MGraph G,Status (* Visit)(MGraph G,unsigned v)); //对图G用Visit"深度优先遍历"

void BFSTraverse(MGraph G,Status (* Visit)(MGraph G,unsigned v));

//对图G用Visit"广度优先遍历",使用队列Q存放访问优先次序

Status ShowVertex(MGraph G,unsigned v); //显示顶点v之值的接口函数,用以展示遍历序列

void ShortestPath_DIJ(MGraph G,unsigned v0,PathMatrix &P,ShortPathTable &D); //Dijkstra算法: 求从有向网G的'(v0)+1'号顶点到其余各顶点之

//最短路径P[v] 及路径的带权长度D[v]. 并列表显示之

/***以下是"队列"相关定义***/

#define MAXQSIZE MAX_VER_NUM+1

//循环队列将多用一个元素空间以区分"满"与"空"

typedef unsigned QElemType;

//unsigned型,用以存放顶点编号(从一开始)

typedef struct

{QElemType *base; //队列起始位

int front,rear;} //首/尾下标,front标示列首元素

//rear标示列尾元素后一位置

SqQueue; //用数组存储的"循环队列"数据结构

Status InitQueue(SqQueue &Q); //初始化一个空队列Q

int QueueLength(SqQueue Q); //返回队列Q的长度

inline Status QueueEmpty(SqQueue Q); //判断队列Q是否为空inline Status QueueFull(SqQueue Q); //判断队列Q是否为满

Status EnQueue(SqQueue &Q,QElemType e); //元素e进入队列Q

Status DeQueue(SqQueue &Q,QElemType &e); //队列Q的队首元素出列,并将其值赋给

e

/***以下是"队列"子程序***/

Status InitQueue(SqQueue &Q)

//初始化一个空队列Q

{Q.base=new QElemType[MAXQSIZE];

if(!Q.base) exit(OVERFLOW); //开辟空间失败

Q.front=Q.rear=0;

return OK;} //InitQueue

int QueueLength(SqQueue Q)

//返回队列Q的长度

{return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;} //QueueLength // ~~~~~~~~~~~~~~ 可能<0,故"+MAXQSIZE"

inline Status QueueEmpty(SqQueue Q)

//判断队列Q是否为空

{if(Q.front==Q.rear) return TRUE;

else return FALSE;} //QueueEmpty inline Status QueueFull(SqQueue Q)

//判断队列Q是否为满

{if(Q.front== (Q.rear+1)%MAXQSIZE) return TRUE;

else return FALSE;} //QueueFull

Status EnQueue(SqQueue &Q,QElemType e)

//元素e进入队列Q

{if(QueueFull(Q)) return ERROR; //队列满

Q.base[Q.rear]=e;

Q.rear=(Q.rear+1)%MAXQSIZE; //以"%"实现可能的回卷return OK;} //EnQueue

Status DeQueue(SqQueue &Q,QElemType &e)

//队列Q的队首元素出列,并将其值赋给e

{if(QueueEmpty(Q)) return ERROR; //队列空

e=Q.base[Q.front];

Q.front=(Q.front+1)%MAXQSIZE; //以"%"实现可能的回卷return OK;} //DeQueue

/***以下是"图"子程序***/

unsigned LocateVex(MGraph G,VertexType v)

//在图G中查找值为v的顶点,并返回其位置

{int i;

for(i=0;i

if(G.vexs[i]==v) return i; //返回数组下标

return NOTFOUND;} //LocateVex

unsigned FirstAdjVex(MGraph G,unsigned n)

//返回编号为n顶点的第一个邻接顶点

{VRType *head,dflt; //default VR value

int ano=G.vexnum; //剩余最多可搜索弧数

if(G.kind==DG||G.kind==UDG) dflt=0; //图

else if(G.kind==DN||G.kind==UDN) dflt=INFINITY; //网else exit(ERROR);

for(head=G.arcs[n-1]; *head==dflt && ano; head++,ano--);

if(!ano) head--; //防止head越界

if(*head!=dflt) return head-G.arcs[n-1]+1; //返回顶点编号//Creat时约定VertexNumber>=2,可防止head不动else return NOTFOUND;

} //FirstAdjVex unsigned NextAdjVex(MGraph G,unsigned n,unsigned adj)

//返回编号为n顶点的,相对其邻接顶点adj的下一个邻接顶点

{VRType *head,dflt; //default VR value

int ano=G.vexnum-adj; //剩余最多可搜索弧数

if(G.kind==DG||G.kind==UDG) dflt=0; //图

else if(G.kind==DN||G.kind==UDN) dflt=INFINITY; //网

else exit(ERROR);

for(head=G.arcs[n-1]+adj; *head==dflt && ano; head++,ano--);

//从adj后一条边/弧开始搜索

if(!ano) head--; //防止head越界,但可能造成head不动

if(*head!=dflt && head!=G.arcs[n-1]+adj-1) return head-G.arcs[n-1]+1;

//防止head不动~~ \\返回顶点编号

// "-1"是因为head指针按"下标"标准运算,

// 而adj是顶点编号(从1开始)

else return NOTFOUND;

} //NextAdjVex

void CreateGraph(MGraph &G,GraphKind kind)

//采用邻接矩阵表示法,构造kind类型的图G

{int vno,ano,i,j,k;

back1:

cout<<"\nThe Vertex_Number=";

cin>>vno; //输入顶点数

if(vno<2 || vno>=MAX_VER_NUM)

{cout<<"非法的顶点数,请重新输入!";

goto back1;

} //if

back2:

cout<<"The Arc_Number=";

cin>>ano; //输入弧数

if(kind==DG||kind==DN)

{if(ano<0 || ano>(vno-1.0)*vno)

{cout<<"非法的弧数,请重新输入!\n";

goto back2;

} //if

} //if

else if(kind==UDG||kind==UDN)

{if(ano<0 || ano>(vno-1.0)*vno/2)

{cout<<"非法的边数,请重新输入!\n";

goto back2;

} //if

} //if

G.vexnum=vno,G.arcnum=ano;

G.kind=kind;

cout<<"\n请依次输入各顶点的信息(字符型),不得重复:\n"; for(i=0;i

{cout<<"V"<<(i+1)<<" = ";

cin>>G.vexs[i]; //输入顶点信息

for(j=0;j

if(G.vexs[j]==G.vexs[i]) //输入的信息与先前信息重复

{i--; //重新输入

cout<<"\n请勿输入重复的信息,详见V"<<(j+1)<

continue;

} //if for j

} //for i 构建顶点信息数组

VertexType vt,vh; //弧尾(tail) / 弧头(head) 顶点值

VRType w; //权重

cout<<"\n请务必按格式输入所有弧或边的信息:\n";

if(kind==DG||kind==UDG) //构建"图"的相关操作

{for(i=0;i

for(j=0;j

//初始化邻接矩阵,"图"以0表示非邻接

cout<<"输入格式: tail,head\n\n";

if(kind==DG) //有向图

for(k=0;k

{cout<<"A"<<(k+1)<<" : ";

cin>>vt>>','>>vh;

if(vt==vh) //两点是同一者

{k--;

cout<<"不能和自身相连,请重新输入\n";

continue;

} //if vt==vh

i=LocateVex(G,vt); //vt定位

j=LocateVex(G,vh); //vh定位

if(i==NOTFOUND||j==NOTFOUND) //找不到

{k--;

cout<<"找不到相应的顶点,请重新输入\n";

continue;

} //if NOTFOUND

if(G.arcs[i][j]) //已赋值

{k--;

cout<<"重复赋值错误,请重新输入\n";

continue;

} //if G.arcs[i][j]!=0

G.arcs[i][j]=1; //建立一段弧

} //for if DG

else //无向图

for(k=0;k

{cout<<"E"<<(k+1)<<" : ";

cin>>vt>>','>>vh;

if(vt==vh) //两点是同一者

{k--;

cout<<"不能和自身相连,请重新输入\n";

continue;

} //if vt==vh

i=LocateVex(G,vt);

j=LocateVex(G,vh);

if(i==NOTFOUND||j==NOTFOUND) //找不到

{k--;

cout<<"找不到相应的顶点,请重新输入\n";

continue;

} //if INFINITY

if(G.arcs[i][j]) //已赋值

{k--;

cout<<"重复赋值错误,请重新输入\n";

continue;

} //if G.arcs[i][j]!=0

G.arcs[i][j]=G.arcs[j][i]=1; //建立一对对称弧

} //for if UDG

} //if DG||UDG

else //构建"网"的相关操作

{for(i=0;i

for(j=0;j

//初始化邻接矩阵,"网"以INFINITY表示非邻接

cout<<"输入格式: tail,head,weight\n\n";

if(kind==DN) //有向网

for(k=0;k

{cout<<"A"<<(k+1)<<" : ";

cin>>vt>>','>>vh>>','>>w;

if(vt==vh) //两点是同一者

{k--;

cout<<"不能和自身相连,请重新输入\n";

continue;

} //if vt==vh

i=LocateVex(G,vt); //vt定位

j=LocateVex(G,vh); //vh定位

if(i==NOTFOUND||j==NOTFOUND) //找不到

{k--;

cout<<"找不到相应的顶点,请重新输入\n";

continue;

} //if INFINITY

if(w>=INFINITY) //权值过大

{k--;

cout<<"权值不得超过三位数,请重新输入\n";

continue;

} //if INFINITY

if(G.arcs[i][j]!=INFINITY) //已赋值

{k--;

cout<<"重复赋值错误,请重新输入\n";

continue;

} //if G.arcs[i][j]!=INFINITY

G.arcs[i][j]=w; //建立一段弧

} //for if DN

else //无向网

for(k=0;k

{cout<<"E"<<(k+1)<<" : ";

cin>>vt>>','>>vh>>','>>w;

if(vt==vh) //两点是同一者

{k--;

cout<<"不能和自身相连,请重新输入\n";

continue;

} //if vt==vh

i=LocateVex(G,vt);

j=LocateVex(G,vh);

if(i==NOTFOUND||j==NOTFOUND) //找不到

{k--;

cout<<"找不到相应的顶点,请重新输入\n";

continue;

} //if INFINITY

if(w>=INFINITY) //权值过大

{k--;

cout<<"权值不得超过三位数,请重新输入\n";

continue;

} //if INFINITY

if(G.arcs[i][j]!=INFINITY) //已赋值

{k--;

cout<<"重复赋值错误,请重新输入\n";

continue;

} //if G.arcs[i][j]!=INFINITY

G.arcs[i][j]=G.arcs[j][i]=w; //建立一对对称弧

} //for else UDN

} //if DN||UDN

cout<<"\n-----------------------------";

cout<<"\n\tInputing End!\n\n";

} //CreateGraph

void ShowGraph(MGraph G)

//显示图G的所有信息

{int vno,ano,i,j;

vno=G.vexnum,ano=G.arcnum;

cout<<"The Vertex_Number ="<

switch(G.kind)

{case DG: cout<<"有向图"; break;

case DN: cout<<"有向网"; break;

case UDG:cout<<"无向图"; break;

case UDN:cout<<"无向网"; break;

default: cout<<"类型错误";

} //switch cout<

cout<<"\n顶点信息:";

cout<<"\nVertex: ";

for(i=0;i

printf("V%-2d ",i+1);

cout<<"\n Value: ";

for(i=0;i

printf(" " IOTYPE " ",G.vexs[i]);

cout<<"\n\nPress 'Enter' to continue!\n"; getchar();

cout<<"\n邻接矩阵:";

printf("\n |");

for(i=1;i<=vno;i++)

printf(" %3d",i);

printf("\n");

for(i=0;i<3+4*vno;i++)

printf("-");

printf("\n");

for(i=0;i

{for(j=0;j

{if(!j) printf("%2d|",i+1);

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

{cout<<" ∞"; continue;

} //if >=

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

} //for j

printf("\n");

} //for i

cout<<"\n\n------------------------";

cout<<"\n\tShowing Ended!\n\n";

} //ShowGraph

Status visited[MAX_VER_NUM+1]; //存放是否访问过的标记,0号位闲置Status (* VisitFunc)(MGraph G,unsigned v); //全局函数变量(首地址)

void DFS(MGraph G,unsigned v)

//从第v个顶点出发,深度优先遍历图G。

{unsigned w;

visited[v]=TRUE; //标记为"已访问"

VisitFunc(G,v); //Visit图G的第v个顶点

for(w=FirstAdjVex(G,v); w!=NOTFOUND; w=NextAdjVex(G,v,w))

if(!visited[w]) DFS(G,w); //对v的"未访问"邻接点w调用DFS

} //DFS void DFSTraverse(MGraph G,Status (* Visit)(MGraph G,unsigned v)) //对图G用Visit"深度优先遍历"

{unsigned v;

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

for(v=1;v<=G.vexnum;v++) visited[v]=FALSE; //初始化访问标记数组

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

if(!visited[v]) DFS(G,v); //若顶点v"未访问"则调用DFS

} //DFSTraverse

void BFSTraverse(MGraph G,Status (* Visit)(MGraph G,unsigned v)) //对图G用Visit"广度优先遍历",使用队列Q存放访问优先次序{unsigned u,v,w;

SqQueue Q;

for(v=1;v<=G.vexnum;v++) visited[v]=FALSE; //初始化访问标记数组InitQueue(Q); //初始化辅助队列Q

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

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

{visited[v]=TRUE; //标记为"已访问"

Visit(G,v); //Visit图G的第v个顶点

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

while(!QueueEmpty(Q))

{DeQueue(Q,u); //队首元素出队并置为u

for(w=FirstAdjVex(G,u); w!=NOTFOUND; w=NextAdjVex(G,u,w))

if(!visited[w])

{visited[w]=TRUE; //标记为"已访问"

Visit(G,w); //Visit图G的第w个顶点

EnQueue(Q,w); //w入队列

} //if for w

//访问u的"未访问"邻接点w,并将w入队列Q

} //while

} //if for v

} //BFSTraverse

Status ShowVertex(MGraph G,unsigned v)

//显示顶点v之值的接口函数,用以展示遍历序列

{printf(IOTYPE " -> ",G.vexs[v-1]);} //ShowVertex

void ShortestPath_DIJ(MGraph G,unsigned v0,PathMatrix &P,ShortPathTable &D) //Dijkstra算法: 求从有向网G的'(v0)+1'号顶点到其余各顶点之

//最短路径P[v] 及路径的带权长度D[v]. 并列表显示之

//若P[v][w]==TRUE,则w是从源点到v+1最短路径上的顶点,

//若S[v]!=0,表示v∈集合S,已求得从源点到v+1的最短路径.(详见下)

{unsigned i,j,v,w,min,vno=G.vexnum; //min临时存放"当前最短路径长度"

//为了和课本保持一致,此处的i,j,v,w均表示"下标" (从0开始)

// ~~~~~~~~~~~~~~~ ☆☆☆☆☆//称呼顶点时一概用"x+1点", x=i,j,v,w,v0

unsigned S[MAX_VER_NUM]; //集合S的标记数组,0表示'不在'集合S内;

//非0表示'在',且数字越大进入的时间越晚

for(v=0;v

{S[v]=NULL; //置集合S为空集

D[v]=G.arcs[v0][v]; //默认路径长度为"直接相连"的长度

for(w=0;w

if(D[v]

{P[v][v0]=TRUE;

P[v][v]=TRUE; //v+1 AND v0+1 均在路径上

} //if

} //for v

D[v0]=0; //v0->v0 长度为0

S[v0]=1; //v0顶点加入S集

/*以上完成了初始化

再简要提示一遍:

P:路径顶点矩阵

D:路径长度数组

S:集合标记数组

*/

//下面开始主循环,每次求得源点到某个顶点v+1的最短路径,并加入S集

Status change_v; //标记v是否已改变,防止重复写S[v]

for(i=1;i

{min=INFINITY; //考虑到可能有"无路可通"的点,默认的最近距离为∞

change_v=FALSE;

for(w=0;w

if(!S[w] && D[w]

{v=w; //更改"下一最近顶点"

min=D[w]; //更改"下一最短路径长度"

change_v=TRUE; //v已改变

} //if &&

//for w

if(change_v) S[v]=i+1; //下一最近顶点加入S集

for(w=0;w

if(!S[w] && (min+G.arcs[v][w]

//min对应的是"新加入的" 顶点v的"最短路径"

{D[w]=min+G.arcs[v][w]; //更新最短路径长度数组D[w]

for(j=0;j

//更新最短路径顶点矩阵的P[w][ ] 分量为P[v][ ]

P[w][w]=TRUE; //将自身加入路径

//w的路径P[w][ ] = P[v][ ] + P[w][w]

} //if &&

//for w

} //for i

//下面显示刚刚求得的最短路径及其长度

unsigned Sequence[MAX_VER_NUM];

//按"进入集合S的顺序"存放各顶点下标位置的数组

unsigned SqLen; //Sequence数组的有效长度

for(i=1,SqLen=0;i<=vno;i++,SqLen++) //搜索"进入集合S的次序"为i的顶点{for(j=0;j

if(S[j]==i) break; //找到"进入次序"为i的顶点(j+1)

//该break跳出for j 内循环

if(j==vno) break;

//if 找不到次序为i的顶点,则次序>i者亦不存在,停止搜索

//该break跳出for i 外循环,则本轮SqLen不++

Sequence[i-1]=j; //"第i个进入S"的顶点(j+1),其下标为j

} //for i 该循环建立了集合S按照"进入顺序"排列的索引

printf("\n\n\n\n 路径的源点: V%u (",v0+1);

printf( IOTYPE ")\n\n",G.vexs[v0]);

printf("==================================\n");

printf("终点(值) 长度最短路径的顶点序列\n");

printf("----------------------------------\n");

for(i=0;i

{if(i==v0) continue; //跳过源点自身

printf(" V%u (" IOTYPE ") ",i+1,G.vexs[i]); //终点编号

if(!S[i]) printf(" ∞无,不可通\n"); //此路不通

else

{printf("%6u ",D[i]); //路径长度

for(j=0;j

if(P[i][Sequence[j]]) printf(IOTYPE "→",G.vexs[Sequence[j]]);

//if for j 依照路径顺序打印各顶点编号

printf("\b\b \n"); //抹去最后多余的"→"两个字符,并换行

} //if-else

} //for i

printf("==================================\n\n");

printf("Dijkstra算法求V%u (" IOTYPE,v0+1,G.vexs[v0]);

printf(")的'单源最短路径'演示完毕!\n\n");

} //ShortestPath_DIJ

/***以下是"图"主控程序***/

main()

{MGraph G;

GraphKind kind;

int choice; cout<<"Copyright(c) Marine.Marion马瑞,All Rights Reserved!\n"; cout<<"Email : marion@https://www.doczj.com/doc/d618791791.html, / m_marion@https://www.doczj.com/doc/d618791791.html,\n";

cout<<"Mobile: 131********\n";

cout<<"\n\t******************************************\n";

cout<<"\tFunctions of DataStructure 'Graph' Release\n";

cout<<"\t******************************************\n\n";

cout<<"本程序选用ASCII字符区分各顶点,顶点的值互不相同.\n";

cout<<"最大支持"<

cout<<"支持的'图'类型有:DG,DN,UDG,UDN.\n";

cout<<"分别表示: 有向图,有向网,无向图,无向网.\n";

cout<<"\n";

cout<<"Press 'Enter' to continue!\n";

getchar();

again1:

cout<<"\n请用数字选择你将要建立的图的类型\n";

cout<<"1)DG, 2)DN, 3)UDG, 4)UDN :\n";

cin>>choice;

switch(choice)

{case 1:kind=DG; break;

case 2:kind=DN; break;

case 3:kind=UDG; break;

case 4:kind=UDN; break;

default:cout<<"\nWrong Choice!\n"; goto again1;

} //switch

CreateGraph(G,kind);

cout<<"Press 'Enter' to continue!\n";

getchar();

cout<<"\n已建立的图是:\n";

ShowGraph(G);

cout<<"Press 'Enter' to continue!\n\n";

getchar();

cout<<"\n对该图进行深度优先遍历(DFS)得到的顶点访问序列为:\n"; DFSTraverse(G,ShowVertex);

cout<<"结束\n";

cout<<"\n对该图进行广度优先遍历(BFS)得到的顶点访问序列为:\n"; BFSTraverse(G,ShowVertex);

cout<<"结束\n";

cout<<"\n Create a new Graph again?(y/n)";

//重新建立一幅图进行演示

if(getchar()=='y')

{getchar(); //清回车

goto again1;

} //if

cout<<"\n\n\t--------------------------------------\n";

cout<<"\t下面演示Dijkstra 算法求'单源最短路径'\n";

cout<<"\t--------------------------------------\n";

again2:

cout<<"\n请重新输入一个有向网(DN):\n";

CreateGraph(G,DN);

cout<<"Press 'Enter' to continue!\n";

getchar();

cout<<"\n已建立的有向网是:\n";

ShowGraph(G);

cout<<"Press 'Enter' to continue!\n";

getchar();

VertexType value;

unsigned position;

PathMatrix PM; //存放"顶点是否在路径上"标记的矩阵ShortPathTable SPT; //存放"从源点到各顶点最短路径"的数组

back:

cout<<"\n选择一个顶点做源点,请输入它的值: "; cin>>value;

position=LocateVex(G,value); //value定位

//注意position是数组下标if(position==NOTFOUND) //找不到

{cout<<"找不到相应的顶点,请重新输入!\n\n";

goto back;

} //if NOTFOUND

ShortestPath_DIJ(G,position,PM,SPT);

cout<<"是否另选择一个顶点做源点?(y/n)";

if(getchar()=='y')

{getchar(); //清回车

goto back;

} //if

getchar(); //清回车

cout<<"\n Try 'Dijkstra' in another Graph?(y/n)";

//换一幅图演示Dijkstra算法

if(getchar()=='y')

{getchar(); //清回车

cout<

goto again2;

} //if cout<<"\n\n--------------------------------\n"; cout<<"Thank you for use this Software!\n"; cout<<"\tPowered by 马瑞";

} //main

请重新输入一个有向网(DN):

The Vertex_Number=6

The Arc_Number=8

请依次输入各顶点的信息(字符型),不得重复: V1 = 0

V2 = 1

V3 = 2

V4 = 3

V5 = 4

V6 = 5

请务必按格式输入所有弧或边的信息:

输入格式: tail,head,weight

A1 : 0,5,100

A2 : 0,4,30

A3 : 4,5,60

A4 : 4,3,20

A5 : 3,5,10

A6 : 0,2,10

A7 : 1,2,5

A8 : 2,3,50

-----------------------------

Inputing End!

Press 'Enter' to continue!

已建立的有向网是: The Vertex_Number =6

The Arc/Edge_Number =8

The GraphKind: 有向网

顶点信息:

Vertex: V1 V2 V3 V4 V5 V6

Value: 0 1 2 3 4 5 Press 'Enter' to continue!

邻接矩阵:

| 1 2 3 4 5 6

---------------------------

1| ∞∞ 10 ∞ 30 100

2| ∞∞ 5 ∞∞∞

3| ∞∞∞ 50 ∞∞

4| ∞∞∞∞∞ 10

5| ∞∞∞ 20 ∞ 60

6| ∞∞∞∞∞∞

------------------------

Showing Ended!

Press 'Enter' to continue!

选择一个顶点做源点,请输入它的值: 0

路径的源点: V1 (0)

==================================

终点(值) 长度最短路径的顶点序列

----------------------------------

V2 (1) ∞无,不可通

V3 (2) 10 0→2

V4 (3) 50 0→4→3

V5 (4) 30 0→4

V6 (5) 60 0→4→3→5

==================================

Dijkstra算法求V1 (0)的'单源最短路径'演示完毕! 是否另选择一个顶点做源点?(y/n)n

Try 'Dijkstra' in another Graph?(y/n)y

请重新输入一个有向网(DN):

The Vertex_Number=3

The Arc_Number=2

请依次输入各顶点的信息(字符型),不得重复:

V1 = a

V2 = b

V3 = c 请务必按格式输入所有弧或边的信息: 输入格式: tail,head,weight

A1 : a,b,55

A2 : b,c,66

-----------------------------

Inputing End!

Press 'Enter' to continue!

已建立的有向网是:

The Vertex_Number =3

The Arc/Edge_Number =2

The GraphKind: 有向网

顶点信息:

Vertex: V1 V2 V3

Value: a b c

Press 'Enter' to continue!

邻接矩阵:

| 1 2 3

---------------

1| ∞ 55 ∞

2| ∞∞ 66

3| ∞∞∞

------------------------

Showing Ended!

Press 'Enter' to continue!

选择一个顶点做源点,请输入它的值: b

路径的源点: V2 (b)

==================================

终点(值) 长度最短路径的顶点序列

----------------------------------

V1 (a) ∞无,不可通

V3 (c) 66 b→c

==================================

Dijkstra算法求V2 (b)的'单源最短路径'演示完毕! 是否另选择一个顶点做源点?(y/n)y

选择一个顶点做源点,请输入它的值: a

路径的源点: V1 (a) ==================================

终点(值) 长度最短路径的顶点序列

----------------------------------

V2 (b) 55 a→b

V3 (c) 121 a→b→c

==================================

Dijkstra算法求V1 (a)的'单源最短路径'演示完毕!

相关主题
文本预览
相关文档 最新文档