#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. JavaScript中的三种弹出框的区别与使用

    JavaScript中有三种原生的弹出框,分别是alert.confirm.prompt.分别表示弹出框.确认框.信息框. 以下是示例代码: <!DOCTYPE html> <htm ...

  2. Java学习笔记44(多线程一:Thread类)

    多线程的概念:略 多线程的目的:提高效率 主线程: package demo; //主线程 public class Demo { public static void main(String[] a ...

  3. 视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频

      视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频  2018-07-11 |  标签»下载, 下载工具, 视频 又是视频下载,老生常谈的话题.阿刚同学已在乐软博客多次与大家分享推荐 ...

  4. Linux学习笔记《六》

  5. Taglist: Exuberant ctags (http://ctags.sf.net) not found in PATH. Plugin is not loaded

    1 开发环境 Ubuntu16.04(64bit) 2 错误描述 安装好Vim的TagList插件后,打开Vim提示: 3 解决方法 根据参考资料[1]的提示,可知那是因为当前系统没有安装ctags导 ...

  6. Strom

    storm    实时分析概念        离线分析             通常是 需要一段时间的数据积累 积累到一定数量数据后 开始离线分析 无论数据量多大 离线分析 有开始 也有结束 最终得到 ...

  7. 抽象语法树(AST)

    AST描述 在计算机科学中,抽象语法树(AST)或语法树是用编程语言编写的源代码的抽象语法结构的树表示.树的每个节点表示在源代码中出现的构造.语法是“抽象的”,因为它不代表真实语法中出现的每个细节,而 ...

  8. python中合并数组的方法

    一.数组纵向合并 1.使用np.vstack()函数 [code] #数组 a = [[1,2,3],[4,5,6]] b = [[1,1,1],[2,2,2]] #纵向合并 c = np.vstac ...

  9. 《ASP.NET Core跨平台开发从入门到实战》Web API自定义格式化protobuf

    <ASP.NET Core跨平台开发从入门到实战>样章节 Web API自定义格式化protobuf. 样章 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于 ...

  10. xshell 会话管理器快捷键

    有没有发现xshell6关闭左边的会话管理器以后,打开就比较麻烦 那么可以自定义一个快捷键来打开: 然后输入一个快捷键 类型选择 菜单-->然后找会话管理器 完事儿 也可以自定义其他快捷键.自己 ...