有向图数据写入邻接表 并Dijkstra算法求最短路径
来源:互联网 发布:路径动画导入unity3d 编辑:程序博客网 时间:2024/04/29 00:43
较之上一篇只是增加了Dijkstra函数
#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#define MAX 100#define INF 1000//(~(0x1<<31)) // 最大值(即0X7FFFFFFF)#define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))#define LENGTH(a) (sizeof(a)/sizeof(a[0]))// 邻接表中表对应的链表的顶点typedef struct _ENode{ int ivex; // 该边的顶点的位置 int weight; // 该边的权 struct _ENode *next_edge; // 指向下一条弧的指针}ENode, *PENode;// 邻接表中表的顶点typedef struct _VNode{ char data; // 顶点信息 ENode *first_edge; // 指向第一条依附该顶点的弧}VNode;// 邻接表typedef struct _LGraph{ int vexnum; // 图的顶点的数目 int edgnum; // 图的边的数目 VNode vexs[MAX];}LGraph;/* * 返回ch在matrix矩阵中的位置 */static int get_position(LGraph G, char ch){ int i; for(i=0; i<G.vexnum; i++) if(G.vexs[i].data==ch) return i; return -1;}/* * 读取一个输入字符 *//* * 将node链接到list的末尾 */static void link_last(ENode *list, ENode *node){ ENode *p =list; while(p->next_edge) p = p->next_edge; p->next_edge = node;}// 边的结构体typedef struct _edata{ char start; // 边的起点 char end; // 边的终点 int weight; // 边的权重}EData;// 顶点static char gVexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};// 边static EData gEdges[] = { // 起点 终点 权 {'A', 'B', 12}, {'A', 'F', 16}, {'A', 'G', 14}, {'B', 'C', 10}, {'B', 'F', 7}, {'C', 'D', 3}, {'C', 'E', 5}, {'C', 'F', 6}, {'D', 'E', 4}, {'E', 'F', 2}, {'E', 'G', 8}, {'F', 'G', 9}, };/* * 创建邻接表对应的图(用已提供的数据) */LGraph* create_example_lgraph(){ char c1, c2; int vlen = LENGTH(gVexs); int elen = LENGTH(gEdges); int i, p1, p2; int weight; LGraph* pG;ENode *q=NULL; if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL ) return NULL; memset(pG, 0, sizeof(LGraph)); // 初始化"顶点数"和"边数" pG->vexnum = vlen; pG->edgnum = elen; // 初始化"邻接表"的顶点 for(i=0; i<pG->vexnum; i++) { pG->vexs[i].data = gVexs[i]; pG->vexs[i].first_edge = NULL; } // 初始化"邻接表"的边 for(i=0; i<pG->edgnum; i++) { // 读取边的起始顶点,结束顶点,权 c1 = gEdges[i].start; c2 = gEdges[i].end; weight = gEdges[i].weight; p1 = get_position(*pG, c1); p2 = get_position(*pG, c2); // 初始化node1 q=(ENode *)malloc(sizeof(ENode));//创建一个表结点 if(q==NULL) return 0; q->ivex=p2;q->weight = weight; // cin>>q->data; q->next_edge=pG->vexs[p1].first_edge;//新加入的节点都是在头结点之后,原来在头结点之后的节点要后移。 pG->vexs[p1].first_edge=q; } return pG;}/* * 打印邻接表图 */void print_lgraph(LGraph G){ int i; ENode *node; printf("List Graph:\n"); for (i = 0; i < G.vexnum; i++) { printf("%d(%c): ", i, G.vexs[i].data); node = G.vexs[i].first_edge; while (node != NULL) { printf("%d(%c) ", node->ivex, G.vexs[node->ivex].data); node = node->next_edge; } printf("\n"); }}/* * 获取G中边<start, end>的权值;若start和end不是连通的,则返回无穷大。 */int get_weight(LGraph G, int start, int end){ ENode *node; if (start==end) return 0; node = G.vexs[start].first_edge; while (node!=NULL) { if (end==node->ivex) return node->weight; node = node->next_edge; } return INF;}/* * Dijkstra最短路径。 * 即,统计图(G)中"顶点vs"到其它各个顶点的最短路径。 * * 参数说明: * G -- 图 * vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。 * prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。 * dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。 */void dijkstra(LGraph G, int vs, int prev[], int dist[]){ int i,j,k; int min; int tmp; int flag[MAX]; // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。 // 初始化 for (i = 0; i < G.vexnum; i++) { flag[i] = 0; // 顶点i的最短路径还没获取到。 prev[i] = 0; // 顶点i的前驱顶点为0。 dist[i] = get_weight(G, vs, i); // 顶点i的最短路径为"顶点vs"到"顶点i"的权。 } // 对"顶点vs"自身进行初始化 flag[vs] = 1; dist[vs] = 0; // 遍历G.vexnum-1次;每次找出一个顶点的最短路径。 for (i = 1; i < G.vexnum; i++) { // 寻找当前最小的路径; // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。 min = INF; for (j = 0; j < G.vexnum; j++) { if (flag[j]==0 && dist[j]<min) { min = dist[j]; k = j; } } // 标记"顶点k"为已经获取到最短路径 flag[k] = 1; // 修正当前最短路径和前驱顶点 // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。 for (j = 0; j < G.vexnum; j++) { tmp = get_weight(G, k, j); tmp = (tmp==INF ? INF : (min + tmp)); // 防止溢出 if (flag[j] == 0 && (tmp < dist[j]) ) { dist[j] = tmp; prev[j] = k; } } } // 打印dijkstra最短路径的结果 printf("dijkstra(%c): \n", G.vexs[vs].data); for (i = 0; i < G.vexnum; i++) printf(" shortest(%c, %c)=%d\n", G.vexs[vs].data, G.vexs[i].data, dist[i]);}void main(){ int prev[MAX] = {0}; int dist[MAX] = {0}; LGraph* pG; // 自定义"图"(自己输入数据) //pG = create_lgraph(); // 采用已有的"图" pG = create_example_lgraph(); print_lgraph(*pG); // 打印图 //DFSTraverse(*pG); // 深度优先遍历 //BFS(*pG); // 广度优先遍历 //prim(*pG, 0); // prim算法生成最小生成树 //kruskal(*pG); // kruskal算法生成最小生成树 // dijkstra算法获取"第4个顶点"到其它各个顶点的最短距离 dijkstra(*pG, 2, prev, dist);int h=get_weight(*pG, 1, 6);printf("%d ",h);}
0 0
- 有向图数据写入邻接表 并Dijkstra算法求最短路径
- Dijkstra算法 求单源含权最短路径(邻接表有向图)C实现
- 有向图数组数据写入邻接表
- Java邻接表表示加权有向图,附dijkstra最短路径算法
- [C++]C++ STL Dijkstra算法 带权有向图(邻接表)单源最短路径求解
- 有向图中Dijstra最短路径算法的邻接表实现
- 算法-dijkstra求最短路径(邻接表实现)
- 有向加权图的最短路径算法-Dijkstra
- Dijkstra最短路径算法(针对加权有向图)
- Dijkstra算法实现有向图单源最短路径
- 图之Dijkstra算法(邻接表)---最短路径
- 最短路径(邻接表)-Dijkstra算法
- 邻接表存储有向图并计算出入度
- 有向图-邻接表
- ACM 模板--邻接表 有向图 搜索算法
- Dijkstra算法,Bellman-Ford算法和BFS算法解决有向图的单源最短路径问题
- 有向图的无权图最短路径算法与带权图的Dijkstra算法
- 图算法 单源最短路径 Dijkstra算法(邻接表/邻接矩阵+优先队列STL)
- 安装 Yii
- 《数据结构与算法》-单链表基本操作的C语言实现
- ORACLE数据字典
- Unity3d_AssetPostprocessor简单用法
- TCP/IP协议 1 ----实验楼转
- 有向图数据写入邻接表 并Dijkstra算法求最短路径
- 华为笔试题
- Spring 注解学习手札(二) 控制层梳理
- Hadoop如何计算map数和reduce数
- GCD详细介绍
- java 中的this 关键字的用法
- 美国付费电视行业2015年财报大集合
- 多个Activity轮训切换的实现
- ExtJs布局详解