#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. Java 实现网络图片的读取与下载

    //网络图片的下载,读取与删除 public static void fileDowAndDel(String httpurl){ try { URL url = new URL(httpurl); ...

  2. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

  3. ES6教程-字符串,函数的参数,了解函数的arguments对象,js面向对象,设计模式-单例模式,解构赋值

    前言 主要讲解了ES6对字符串的拓展,包括includes,startsWith和endsWith,另外增加了字符串模板. Start includes()是否包含 startsWith()以什么开头 ...

  4. ASP.NET MVC 异常Exception拦截

    一.前言 由于客户端的环境不一致,有可能会造成我们预计不到的异常错误,所以在项目中,友好的异常信息提示,是非常重要的.在asp.net mvc中实现异常属性拦截也非常简单,只需要继承另一个类(Syst ...

  5. Spring Boot 核心配置文件 bootstrap & application 详解。

    用过 Spring Boot 的都知道在 Spring Boot 中有以下两种配置文件 bootstrap (.yml 或者 .properties) application (.yml 或者 .pr ...

  6. linux系统添加swap(虚拟内存)分区

    ​ 在实际的生产环境中,实际的物理内存我们经常会觉得不够用,增加物理内存的成本又比较高,一种折中方案就出来了,使用硬盘的一部分空间来做Swap(windows 下叫虚拟内存),将系统内非活动内存换页到 ...

  7. spring boot -thymeleaf-逻辑控制

    th:if th:switch

  8. oracle生成AWR报告方法

    2018-04-02 19:59:42 在10g 11g中AWR自动的每隔一小时进行一次数据采集并生成快照.下面是生成AWR报告的步骤: 1:使用oracle用户在数据库服务器上执行如下命令 sqlp ...

  9. [原创]K8_Delphi源码免杀系列教程

    [原创]K8_Delphi源码免杀系列教程[2014] 虽是2014年的,但免杀思路方法并未过时 比如函数动态调用\代码注释法等至今依然有效 链接:https://pan.baidu.com/s/1H ...

  10. textarea 赋值的方法

    textarea 赋值的方法 <textarea name="" rows="3" id="note21" ></text ...