图论算法之最短路径(有向无权图)
来源:互联网 发布:powell算法 编辑:程序博客网 时间:2024/05/20 08:22
1.算法介绍
下图是一个无权图G。使用某个顶点s作为输入参数,我们想要找出从s到所有其他顶点的最短路径。
设我们选择s为v2.此时立刻可以说出从s到v2的最短路径长为0的路径。把这个信息做个标记。如下图。
现在我们可以开始找寻所有与s距离为1的顶点。这些顶点通过考查与s邻接的那些顶点可以找到。此时我们看到,v0和v5与s出发只有一步之遥。标记如下。
现在可以找出那些从s出发最短路径恰为2的顶点。找到所有邻接到v0和v5的顶点。它们的最短路径还不知道。这次搜索告诉我们,到v1和v3的最短路径长为2。标记如下。
最后,通过考查那些与刚被赋值的v1和v3相邻的顶点我们可以发现。v4和v6各有一条三边最短路径。标记如下。
这种搜索一个图的方法称为广度优先搜索。该方法按层处理顶点。距开始点最近的那些顶点首先被赋值。而最远的那些顶点最后被赋值。
2 算法实现
对于每个顶点。我们将跟踪三个信息。首先,我们把从s开始到顶点的距离放在dist中。开始的时候,除s外所有顶点都是不可达到的。另外我们记录引起顶点变化的最后一个节点path。最后如果顶点被处理过,将使用known标记。
算法的实现需要使用队列和链表。我把它们放在附录中。
核心算法是unWeighted函数initGraph和initArr负责初始化图G。
//// main.c// Unweighted2//// Created by Wuyixin on 2017/6/11.// Copyright © 2017年 Coding365. All rights reserved.//#include <stdio.h>#include "LinkList.h"#include "Queue.h"typedef LinkedList Graph,Vertex;Graph initGraph(int n ,int g[n][n]);void initArr(int n ,int g[n][n]);/* 为了初始化方便,使用二维数组初始化图。实际上这是不允许的,因为使用链表就是为了避免使用二维数组*/Graph initGraph(int n ,int a[n][n]){ Graph g; Vertex v,w; g = malloc(n * sizeof(struct Node)); if (g == NULL) exit(EXIT_FAILURE); /* 初始化顶点 */ for (int i = 0; i < n; i++) { g[i].data = i; g[i].next= NULL; g[i].dist = INT_MAX; g[i].known = 0; g[i].path = 0; } for (int i = 0; i < n; i++) { /* 构建顶点 */ v = &g[i]; for (int j = 0; j < n; j++) { /* 构建邻接顶点 */ if (a[i][j] != UNAVAILABLE){ w = malloc(sizeof(struct Node)); if (w == NULL) exit(EXIT_FAILURE); w->data = j; w->next = NULL; v->next = w; v = w; } } } return g;}/* 初始化二维数组 */void initArr(int n ,int g[n][n]){ for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) g[i][j] = UNAVAILABLE; }void unWeighted(Graph g,int s,int n){ if (g == NULL) exit(EXIT_FAILURE); Queue q; Vertex v,w,z; int i; q = createQueue(n); makeEmpty(q); g[s].dist = 0; g[s].known = 1; enQueue(s, q); while (!isEmpty(q)) { i = deQueue(q); v = &g[i]; for (w = v->next; w != NULL; w = w->next) { z = &g[w->data]; if (z->known == 0){ z->dist = v->dist + 1; z->path = v->data; z->known = 1; enQueue(w->data, q); } } } disposeQueue(q);/* free queue */}void printDist(Graph g,int n){ for (int i = 0 ; i < n; i++) printf("v%d--dist:%d ",i,g[i].dist); printf("\n");}int main(int argc, const char * argv[]) { int a[7][7]; initArr(7, a); a[0][1] = 1; a[0][3] = 1; a[1][3] = 1; a[1][4] = 1; a[2][0] = 1; a[2][5] = 1; a[3][2] = 1; a[3][4] = 1; a[3][5] = 1; a[3][6] = 1; a[3][4] = 1; a[4][6] = 1; a[6][5] = 1; Graph g; g = initGraph(7, a); unWeighted(g , 2, 7); printDist(g, 7); return 0;}
3.附录:队列与链表
3.1 队列
(1)头文件
//// Queue.h// Unweighted//// Created by Wuyixin on 2017/6/6.// Copyright © 2017年 Coding365. All rights reserved.//#ifndef Queue_h#define Queue_h#include <stdio.h>#include <stdlib.h>#include <limits.h>typedef int ElemType;typedef struct QueueRecord *Queue;struct QueueRecord{ int capacity; int front; int rear; int size; ElemType *array;};/* 是否空 */int isEmpty(Queue q);/* 是否满 */int isFull(Queue q);/* 创建队列 */Queue createQueue(int maxElement);/* 销毁队列 */void disposeQueue(Queue q);/* 置空 */void makeEmpty(Queue q);/* 入队 */void enQueue(ElemType x, Queue q);/* 出队 */ElemType deQueue( Queue q);#endif /* Queue_h */
(2)实现文件
//// Queue.c// Unweighted//// Created by Wuyixin on 2017/6/6.// Copyright © 2017年 Coding365. All rights reserved.//#include "Queue.h"/* 是否空 */int isEmpty(Queue q){ return q->size == 0;}/* 是否满 */int isFull(Queue q){ return q->front % (q->capacity) == (q->rear + 2) % q->capacity;}/* 创建队列 */Queue createQueue(int maxElement){ if (maxElement <= 0) exit(EXIT_FAILURE); Queue q = malloc(sizeof(struct QueueRecord)); if (q == NULL) exit(EXIT_FAILURE); ElemType* array = malloc(maxElement * sizeof(ElemType)); if (array == NULL) exit(EXIT_FAILURE); q->array = array; q->capacity = maxElement + 1; makeEmpty(q); return q;}/* 销毁队列 */void disposeQueue(Queue q){ if (q != NULL){ free(q->array); free(q); }}/* 置空 */void makeEmpty(Queue q){ q->size = 0; q->front = 1; q->rear = 0;}/* 入队 */void enQueue(ElemType x, Queue q){ if (!isFull(q)){ q->rear = (q->rear + 1) % q->capacity; q->size += 1; q->array[q->rear] = x; }}/* 出队 */ElemType deQueue(Queue q){ if (!isEmpty(q)){ int tmp = q->front; q->front = (q->front + 1) % q->capacity; q->size -= 1; return q->array[tmp]; } return INT_MIN;}
3.2 链表
(1)头文件
//// LinkList.h// Unweighted//// Created by Wuyixin on 2017/6/6.// Copyright © 2017年 Coding365. All rights reserved.//#ifndef LinkList_h#define LinkList_h#include <stdio.h>#include <limits.h>#include <stdlib.h>extern int UNAVAILABLE;typedef struct Node *LinkedList,*PtoNode;typedef int ElemType;struct Node{ ElemType data; struct Node* next; int dist; int known; int path;};/* 链表初始化 */LinkedList initList();/* 插入元素 */ElemType insert(ElemType x,LinkedList list);/* 删除链表 */void deleteList(LinkedList list);/* 打印链表 */void printList(LinkedList list);#endif /* LinkList_h */
(2)实现文件
//// LinkList.c// Unweighted//// Created by Wuyixin on 2017/6/6.// Copyright © 2017年 Coding365. All rights reserved.//#include "LinkList.h"int UNAVAILABLE = INT_MIN;/* 链表初始化 */LinkedList initList(){ LinkedList h = malloc(sizeof(struct Node)); if (h == NULL) exit(EXIT_FAILURE); h->next = NULL; h->data = UNAVAILABLE; return h;}/* 插入元素 */ElemType insert(ElemType x,LinkedList list){ PtoNode current; current = list; while (current->next != NULL) current = current->next; /* 生成新节点 */ PtoNode n = (PtoNode)malloc(sizeof(struct Node)); if (n == NULL) exit(EXIT_FAILURE); n->data = x; n->next = NULL; current->next = n; return x;}/* 删除链表 */void deleteList(LinkedList list){ if (list == NULL) return; PtoNode node,old; node = list; while (node->next != NULL){ old = node; node = node->next; free(old); }}/* 打印链表 */void printList(LinkedList list){ PtoNode node; node = list->next; while (node!= NULL ) { printf("%d ",node->data); node = node->next; } printf("\n");}
阅读全文
0 0
- 图论算法之最短路径(有向无权图)
- 图(二)—— 一个有向无权图的最短路径算法
- 图(二)—— 一个有向无权图的最短路径算法
- 图论之无权最短路径
- 无权图-最短路径
- 有向图的最短路径(Floyd算法)
- 打印无权无向图的所有最短路径
- 无向无权图的最短路径数
- 无向无权图的最短路径数
- Java找出无权无向图的最短路径
- 图算法 单源最短路径问题 无权最短路径
- 无权图的单源最短路径最短路径算法
- 有向加权图的最短路径算法-Dijkstra
- 有向加权图的最短路径算法-Prim
- Dijkstra最短路径算法(针对加权有向图)
- 有向图的最短路径算法
- 无权图的最短路径
- 最短路径——迪杰斯坷垃算法(有向图、单源最短路径)
- Linux安装Apache
- 图论算法之最短路径(具有负边值的图)
- Android_常用控件
- C语言.动态链表.随笔
- 图论算法之最短路径(Dijkstra算法)
- 图论算法之最短路径(有向无权图)
- 《C语言及程序设计初步》_1.11算术运算符与算术表达式_实践11——如何买玫瑰
- 操作系统实验报告 lab6
- 《C语言及程序设计初步》_1.11算术运算符与算术表达式_实践12——玩数字
- 模式识别——正态训练样本分类估计
- 使用zipkin做分布式链路监控
- 机器学习-梯度下降法
- Oracle存储过程及调用
- java 学习 第三天 java核心类