#include <stdio.h>
#include <stdlib.h> #define ERROR_NO_MEM -1 /*内存不足的错误码*/ #define MAX_POINT_NUM 5 /*最大的点数*/
#define MAX_EDGE_NUM 7 /*最多的边数*/ #define MAX_VALUE 0xfffffff /*最大路径长度*/ /*表示每个结点的信息*/
struct tagEdgeNode
{
int value; /*结点数值*/
struct tagEdgeNode *next; /*指向路径的下一个结点*/
}; /*存储路径的数组*/
typedef struct tagEdgeNode *adjlist[MAX_POINT_NUM]; /*存储图的邻接矩阵*/
typedef int AdjMatrix[MAX_POINT_NUM ][MAX_POINT_NUM ]; /*
释放链表上的动态内存
*/
void freeNode(struct tagEdgeNode *list)
{
struct tagEdgeNode *p = NULL;
struct tagEdgeNode *tmp = NULL; p = list;
while(NULL != p)
{
tmp = p->next; free(p); p = tmp;
} return ;
} /*
显示图的邻接矩阵
*/
void showGraph(AdjMatrix GA)
{
int i;
int j; for(i = ; i < MAX_POINT_NUM; i++)
{
for(j = ; j < MAX_POINT_NUM; j++)
{
if(( MAX_VALUE != GA[i][j] ) && ( != GA[i][j] ))
{
printf("GA[%d][%d] =%d \r\n", i, j, GA[i][j]);
} } printf("\r\n");
} return ;
} /*
修改路径结点
*/
int ChangePath(adjlist path, int m, int j)
{
struct tagEdgeNode *p = NULL;
struct tagEdgeNode *q = NULL;
struct tagEdgeNode *end = NULL; /*清除顶点j的当前最短路径*/
freeNode(path[j]);
path[j] = NULL; /*把到顶点m的最短路径复制到顶点j的最短路径上*/
p = path[m];
while(NULL != p)
{
q = malloc(sizeof(struct tagEdgeNode));
if(NULL == q)
{
/*申请内存失败,释放已有链表*/
freeNode(path[j]);
return ERROR_NO_MEM;
} q->value = p->value;
if( NULL == path[j] )
{
path[j] = q;
}
else
{
end->next = q;
} end = q;
p = p->next;
} /*把顶点j加入到path[j]单链表的最后,形成新的目前最短路径*/
q = malloc(sizeof(struct tagEdgeNode));
if(NULL == q)
{
/*申请内存失败,释放已有链表*/
freeNode(path[j]);
return ERROR_NO_MEM;
} q->value = j;
q->next = NULL; end->next = q; return ;
} /*
查找出从节点i开始到其他所有节点的最短路径(dijkstra算法)
*/
int FindShortestPath(AdjMatrix GA, int dist[], adjlist path, int i)
{
int j, k,w,m;
int newDistance;
int minDistance; int Set[MAX_POINT_NUM]; /*存放已求得最短路径的节点*/
struct tagEdgeNode *p1 = NULL;
struct tagEdgeNode *p2 = NULL; /*初始化Set集合、路径结点集合*/
for(j =; j < MAX_POINT_NUM; j++)
{
if( j == i )
{
Set[j] = ;
}
else
{
Set[j] = ;
} dist[j] = GA[i][j]; /*如果到相邻结点的距离不是无穷大,则记录该路径*/
if(( dist[j] < MAX_VALUE ) && ( j != i))
{
p1 = malloc(sizeof(struct tagEdgeNode));
p2 = malloc(sizeof(struct tagEdgeNode));
if(( NULL == p1) || ( NULL == p2 ))
{
if( NULL != p1 )
{
free(p1);
}
if( NULL != p2 )
{
free(p2);
} return ERROR_NO_MEM;
} p1->value = i;
p2->value = j;
p2->next = NULL;
p1->next = p2;
path[j] = p1;
}
else
{
path[j] = NULL;
}
} /*共计需要n-2次循环, 每次循环选择路径最短的作为起点*/
for ( k = ; k <= MAX_POINT_NUM-; k++)
{
/*求出第k个终点m*/
minDistance = MAX_VALUE;
m = i; /*寻找到下一个开始搜寻的节点:条件是不在集合中,而且距起始节点最近*/
for(j = ; j < MAX_POINT_NUM; j++)
{
if(( Set[j] == ) && (dist[j] < minDistance))
{
minDistance = dist[j];
m = j;
}
} /*若条件成立, 则把顶点m并入集合S中, 否则退出循环,因为剩余的顶点,
其最短路径长度均为MAX_VALUE,无需再计算*/
if( m != i)
{
Set[m] = ;
}
else
{
break;
} /*从未排序节点中选择对应dist和path中的元素做必要修改*/
for( j = ; j < MAX_POINT_NUM; j++)
{
newDistance = dist[m] + GA[m][j];
if(( == Set[j] ) && ( newDistance < dist[j] ))
{
dist[j] = newDistance;
ChangePath(path, m, j);
}
}
} /*显示图的最短距离和最短路径*/
printf("next show shortest path as following: \r\n");
for(i = ; i < MAX_POINT_NUM; i++)
{
printf("min distance to [%d] = %d \r\n", i, dist[i]);
printf("path:"); p1 = path[i];
while(NULL != p1)
{
printf(" %d ", p1->value);
p1 = p1->next;
} printf("\r\n\r\n");
} /*释放所有的动态内存*/
for(i = ; i < MAX_POINT_NUM; i++)
{
freeNode(path[i]);
} return ;
} /*
创建图的邻接矩阵。
创建成功时,返回0.
创建失败时,返回错误码
*/
int createGraph(AdjMatrix GA)
{
int i;
int j;
int k;
int weigt; /*初始化邻接数组*/
for(i = ; i < MAX_POINT_NUM; i++)
{
for(j = ; j < MAX_POINT_NUM; j++)
{
if( i == j)
{
GA[i][j] = ;
}
else
{
GA[i][j] = MAX_VALUE;
}
}
} /*建立邻接数组*/
printf("input number from 0 to 4 as edge point. and max 7 link between those points. weigt should less than 0xfffffff\r\n");
printf("input one edge, from i to j, weigh, format is: i j weigt \r\n");
for(k = ; k <= MAX_EDGE_NUM; k++ )
{
/*建立一条边。从i到j. 权值为w <i j w>*/ scanf("%d %d %d", &i, &j, &weigt); /*判断参数合法性*/
if(( i > ) || ( j > ) || (weigt >= MAX_VALUE))
{
printf("invalid i or j or weigt value. i=%d j=%d weigt=%d \r\n", i, j, weigt);
continue;
} GA[i][j] = weigt;
} /* 可以用下面这组作为测试数据,验证算法
GA[0][1] = 1;
GA[0][2] = 2;
GA[1][2] = 3;
GA[1][3] = 1;
GA[1][4] = 3;
GA[3][4] = 1;
GA[2][4] = 2;
*/ return ;
} int main()
{
int ret;
AdjMatrix GA;
adjlist path;
int dist[MAX_POINT_NUM]; ret = createGraph(GA);
if( != ret)
{
printf("error. fail to create Graph");
return ;
} showGraph(GA); ret = FindShortestPath(GA, dist, path, );
if( != ret)
{
printf("error. can not find the short path from point 0 in Graph");
return ;
} return ;
}

图中最短路径的算法--dijiska算法C语言实现的更多相关文章

  1. 图中最短路径算法(Dijkstra算法)(转)

    1.Dijkstra 1)      适用条件&范围: a)   单源最短路径(从源点s到其它所有顶点v); b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E ...

  2. C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)

    1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...

  3. [从今天开始修炼数据结构]图的最短路径 —— 迪杰斯特拉算法和弗洛伊德算法的详解与Java实现

    在网图和非网图中,最短路径的含义不同.非网图中边上没有权值,所谓的最短路径,其实就是两顶点之间经过的边数最少的路径:而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,我们称路径上第 ...

  4. Floyd-Warshall求图中任意两点的最短路径

    原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...

  5. javascript实现有向无环图中任意两点最短路径的dijistra算法

    有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://w ...

  6. 在图中寻找最短路径-----深度优先算法C++实现

    求从图中的任意一点(起点)到另一点(终点)的最短路径,最短距离: 图中有数字的点表示为图中的不同海拔的高地,不能通过:没有数字的点表示海拔为0,为平地可以通过: 这个是典型的求图中两点的最短路径:本例 ...

  7. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  8. python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边

    # Bellman-Ford核心算法 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离 # 循环n-1轮,每轮对m条边进行一次松弛操作 # 定理: # 在一个含有n个顶点的图中,任意 ...

  9. 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)

    文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...

随机推荐

  1. 深入浅出TCP/IP协议

    目录 什么是网络协议? 谁来制定这个网络协议? TCI/IP协议 什么是socket? http协议属于应用层还是传输层? soap可以使用HTTP协议进行传输吗? 各层协议举例 什么是网络协议? 话 ...

  2. C++随机数引擎

    C++的随机数引擎有以下几个要点需要注意:  1.随机数发生器使用同一种子会生成相同序列的随机数序列 2.为了让程序每次运行都会生成不同的随机结果,我们可以使用 time(0) 产生一个随机数种子 3 ...

  3. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. Source Insight函数调用关系显示设置

    当我们需要设置source Insight的项目代码中函数调用关系时,可通过如下的设置来实现: 1.显示函数调用关系窗口 Source Insight工具栏中“View”—>“Relation  ...

  5. vue安装及axios、stylus、iview的安装流程整理

    现在做的项目中主要用到以下几个安装包,所以整理下流程: 使用命令行工具npm新创建一个vue项目 vue中axios的安装和使用 在vue项目中stylus的安装及使用 如何在vue中全局引入styl ...

  6. Django--分页器(paginator)

    1 Django的分页器(paginator)简介 在页面显示分页数据,需要用到Django分页器组件 from django.core.paginator import Paginator Pagi ...

  7. 【OSX】解决编译AOSP时需要10.5/10.6 SDK下载

    有人遇到的是需要10.6的sdk. 公司网快下载了xcode, 把里面的10.5sdk和10.6sdk拿出来, 一共才一百多兆…… 下载链接: http://pan.baidu.com/s/1gdxG ...

  8. Zabbix4.2.0基本配置和邮件报警

    目录 1. 修改中文 2. 添加监控本机 3. 监控本机mysql 4. 配置邮件报警 4.1 添加FTP模板 4.2 报警媒介类型 4.3 配置报警到用户 4.4 配置动作 4.5 模拟FTP故障 ...

  9. 以ActiveMQ为例JAVA消息中间件学习【3】——SpringBoot中使用ActiveMQ

    前言 首先我们在java环境中使用了ActiveMQ,然后我们又在Spring中使用了ActiveMQ 本来这样已经可以了,但是最近SpringBoot也来了.所以在其中也需要使用试试. 可以提前透露 ...

  10. 开发php的扩展模块(centos环境下)

    首先下载一份PHP的源码,并上传到centos服务器上 源码下载地址:https://github.com/php/php-src   然后在命令行进入到源码路径下的ext目录 然后创建扩展项目 [r ...