单源最短路径_单源结点最短路径

 我来答
秃头小李头
2023-03-11 · TA获得超过407个赞
知道小有建树答主
回答量:792
采纳率:100%
帮助的人:75.1万
展开全部
单源结点最短路径

一、题目

单源结点最短路径问题。

二、问题描述

求从有向图的某一结点出发到其余各结点的最短路径。

三、基本要求

(1) 有向图采用邻接矩阵表示。

(2) 单源结点的最短路径问题采用狄克斯特拉算法。

(3) 输出有向图中从源结点到其余各结点的最短路径和最短路径值。

四、测试数据

测试数据为如下图所示的有向带权图,以结点v1作为源结点,求从结点v1到其余各结点的最短路径和最短路径的长度值。

图 有向带权图

五、算法思想

1. 算法流程图

算法流程图

(2)算法分析

按已给有向图构造出图G 结构体,顺序表存储顶点信息,矩阵存储邻接矩阵信息,记录边的条数;选择v1为起始顶点,用狄克斯特拉算法求v1顶点到其他各个顶点的最短路径值和最短距离。

将所有的顶点分为S 、T 两类,S 用来存放已知最短路径的顶点。而T 存放未知最短路径的顶点。如果起始点(v1)到某个相邻顶点的最短距离已经求出,比如v1-v2的距离。那么就把v2归入S ,其余的不能直接算出最短距离的则要归入T 。

刚开始的S 只有起始点一个,随着算法的继续,首先将起始点相邻的点归入到S ,知道最后一个顶点归入S 。

六、模块划分

1. 创建图

(1)算法流程

创建图流程

(2)求得G 图结构如下图所示:

2. 求最短路径和最短距离

算法流程图

(1)求得最短距离矩阵如下

⎡0-1-1-1⎢01-1-1⎢

⎢02-1-1

path [6][6]=⎢

⎢0253⎢0253⎢

⎢025-1⎣

-1-1⎤

-1-1⎥⎥-1-1⎥



-1-1⎥4-1⎥



-1-1⎦⎥

(2)求得最短距离矩阵如下

distance [6]=[[1**********]]

七、数据结构

1. 结构体定义

(1)图的结构体定义

typedef struct {

SeqList Vertices; //存放顶点的顺序表 int edge[MaxVertices][MaxVertices]; //存放边的邻接矩阵 int numOfEdges; }AdjMGraph; (2)边信息结构体定义 typedef struct {

int row; int col;

int weight; }RowColWeight;

八、源程序

1. 子函数AdjMGraph.h

/**邻接矩阵存储存储结构下图操作的实现**/

#ifndef ADJMGRAPH_H_INCLUDED #define ADJMGRAPH_H_INCLUDED

#include "SeqList.h"

typedef struct {

SeqList Vertices; int edge[MaxVertices][MaxVertices]; int numOfEdges; }AdjMGraph;

/**初始化有n 个顶点的顶点顺序表和邻接矩阵**/

//边的条数 //图的结构体定义 //行下标 //列下标 //权值

//边信息结构体定义

//包含顺序表头文件 //存放顶点的顺序表 //存放边的邻接矩阵 //边的条数

//图的结构体定义

void Initiate(AdjMGraph *G, int n) {

int i,j;

for(i=0;i

for(j=0;j

if(i==j) G->edge[i][j]=0;

else G->edge[i][j]=MaxWeight; //MaxWeight 表示无穷大 }

G->numOfEdges=0; //边的条数置为0 ListInitiate(&G->Vertices); //顺序表初始化 }

/**在图中增加一个顶点**/

void InsertVertex(AdjMGraph *G, DataType vertex) //在图中插入顶点vertex {

ListInsert(&G->Vertices,G->Vertices.size,vertex); //顺序表尾插入 }

/**在图中增加一条有向边**/

void InsertEdge(AdjMGraph *G, int v1, int v2, int weight)

//在图G 中插入边,边的权为weight {

if(v1 = G->Vertices.size || v2 = G->Vertices.size) {

printf("参数v1或v2越界出错!\n"); return; }

G->edge[v1][v2] =weight; G->numOfEdges++; }

/**在图中取消一条有向边**/

void DeleteEdge(AdjMGraph *G,int v1,int v2) //在图G 中删除边

if(v1 = G->Vertices.size || v2 = G->Vertices.size || v1 == v2 ) {

printf("参数v1或v2出错\n"); return; }

if(G->edge[v1][v2] == MaxWeight || v1 == v2 ) {

printf("该边不存在!\n"); return; }

G->edge[v1][v2]=MaxWeight; G->numOfEdges--; }

/**取第一个邻接顶点**/

int GetFirstVex(AdjMGraph G,int v)

//在图G 中需要序号为V 的顶点的第一个邻接顶点

//如果这样的邻接顶点存在,则返回该邻接顶点的序号,否则返回-1 {

int col;

if(v = G.Vertices.size) {

printf("参数v1越界!\n"); return -1; }

for(col = 0; col

if(G.edge[v][col]>0&&G.edge[v][col]

return -1; }

/**取下一个邻接顶点**/

int GetNextVex(AdjMGraph G,int v1, int v2)

//在图G 中寻找V1顶点的邻接顶点V2的下一个邻接顶点 {

int col;

if(v1 = G.Vertices.size || v2 = G.Vertices.size) {

printf("参数v1或v2越界出错!\n"); return -1; }

for(col=v2+1;col

if(G.edge[v1][col]>0&&G.edge[v1][col]

return -1; }

#endif // ADJMGRAPH_H_INCLUDED

2. 子函数AdjMGraphCreate.h

/**图的创建函数**/

#ifndef ADJMGRAPHCREATE_H_INCLUDED #define ADJMGRAPHCREATE_H_INCLUDED

typedef struct {

int row; //行下标 int col; //列下标 int weight; //权值

}RowColWeight; //边信息结构体定义

void CreatGraph(AdjMGraph *G,DataType V[],int n,RowColWeight E[],int e) //在图G 中出入n 个顶点信息V 和e 条边的信息E {

int i,k;

Initiate(G,n); //顶点顺序表初始化

for(i=0;i

InsertVertex(G,V[i]); //插入顶点

for(k=0;k

InsertEdge(G,E[k].row,E[k].col,E[k].weight); //插入边

}

#endif // ADJMGRAPHCREATE_H_INCLUDED

3. 子函数Dijkstra.h

#ifndef DIJKSTRA_H_INCLUDED #define DIJKSTRA_H_INCLUDED #define N 6

void Dijkstra(AdjMGraph G, int v1, int distance[], int path[][N])

//带权图G 从下标v1顶点到其他顶点的最短距离distance 和最短路径下标path {

int n=G.Vertices.size;

int *s=(int*)malloc(sizeof(int)*n); int minDis,i,j,u,k;

//初始化

for(i=0;i

path[i][0]=v1; for(j=1;j

for(i=0;i

distance[i]=G.edge[v1][i]; s[i]=0;

if(i!=v1&&distance[i]

//标记顶点v0已从集合T 加入到集合S 中 s[v1]=1;

//在当前还未找到最短路径的顶点集中选取具有最短距离的顶点u for(i=1;i

minDis=MaxWeight;

for(j=0;j

if(s[j]==0 && distance[j]

u=j;

minDis=distance[j]; }

//当已不存在路径时,算法结束。此句对非连通图是必需的 if(minDis==MaxWeight) return;

//标记顶点u 已从集合T 加入到集合S 中 s[u]=1;

//修改从v0到其他顶点的最短路径和最短距离 for(j=0;j

if(s[j]==0 && G.edge[u][j]

//顶点v0经顶点U 到其他顶点的最短距离和最短路径 distance[j]=distance[u]+G.edge[u][j]; for(k=0;path[u][k]!=-1;k++) {

path[j][k]=path[u][k]; }

path[j][k++]=j; path[j][k]=-1; } } } }

#endif // DIJKSTRA_H_INCLUDED

4. 子函数SeqList.h

#ifndef SeqList_H #define SeqList_H

typedef struct { DataType list[MaxSize]; // DataType这个在你用的时候可以去定义它的类型 int size; //指这个表的总长度

}SeqList; //定义抽象数据类型SeqList

void ListInitiate(SeqList *L) // 初始化顺序表L { L->size=0; // 定义初始元素个数 }

int ListLength(SeqList L)

{

return L.size;

}

int ListInsert(SeqList *L,int i,DataType x)

//在顺序表L 的位置i (0

{

int j;

if(L->size >= MaxSize)

{

printf("表已满无法插入!\n");

return 0;

}

else if(iL->size)

{

printf("参数i 不合法!\n");

return 0;

}

else

{

for(j=L->size;j>i;j--)

{

L->list[j]=L->list[j-1];

}

L->list[i]=x;

L->size++;

return 1;

}

}

int ListDelete(SeqList *L,int i,DataType *x)

//删除顺序表L 中位置i 上的数据元素并保存到x 中

//插入成功返回1,否则返回0

{

int j;

if(L->size

{

printf("表已空无法插入!\n");

return 0;

}

else if(iL->size-1)

{

printf("参数i 不合法!\n");

return 0;

}

else

{

*x=L->list[i];

for(j=i+1;jsize-1;j++)

L->list[j-1]=L->list[j];

L->size--;

return 1;

}

}

int ListGet(SeqList L,int i,DataType *x)

//取顺序表L 中第i 个元素的值,取到则返回1,否则返回0

{

if(iL.size-1)

{

printf("参数i 不合法!\n");

return 0;

}

else

{

*x=L.list[i];

return 1;

}

}

int ListNotEmpty(SeqList L)

//判断该表是否为空

//如果表的总长度小于等于0,则说明该表为空,返回1

{

if(L.size

return 0;

else

return 1;

}

#endif

5. 主函数

#include

#include

#include

typedef char DataType;

#define MaxSize 10 //定义顺序表数组的最大值 #define MaxVertices 30 //定义顶点的最大值 #define MaxWeight 10000 // 定义无穷大的具体值

#include "AdjMGraph.h"

#include "AdjMGraphCreate.h"

#include "Dijkstra.h"

int main()

{

AdjMGraph g;

char a[]={"1","2","3","4","5","6"};

RowColWeight rcw[]={{0,1,10},{0,2,12},{1,3,16},{1,4,25},{2,0,4},{2,1,3}, {2,3,12},{2,5,8},{3,4,7},{5,3,2},{5,4,10}}; int i, n=6, e=11,j;

int distance[6], path[6][6];

CreatGraph(&g, a, n, rcw, e);

Dijkstra(g, 0, distance, path);

printf("从顶点v%c到其他各顶点的最短距离为:\n",g.Vertices.list[0]); for(i=0;i

printf("到顶点v%c的最短距离为%d\n",g.Vertices.list[i],distance[i]);

printf("\n从顶点v%c到其他各顶点最短路径为:\n",g.Vertices.list[0]); for(i=0;i

{

printf("\n到顶点v%c的最短路径为:",g.Vertices.list[i]); for(j=0;j

if(path[i][j]!=-1)

printf (" v%c ",g.Vertices.list[path[i][j]]);

}

return 0;

}

九、测试情况

程序运行结果
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式