dijkstra算法
来源:互联网 发布:国内域名 国外服务器 编辑:程序博客网 时间:2024/06/10 04:40
/*dijkstra algorithm
author:wuzuquan
last_modify:2008-1-12
*/
#include <stdio.h>
#include <limits.h>
#define MAX_DIST 10000
#define NIL 10000
#define VNUM 5
#define PARENT(i) ((i)>>1)
#define LEFT(i) ((i)<<1)
#define RIGHT(i) ((LEFT(i))+1)
typedef struct
{
int v;/*顶点u-->v*/
int w;
}edge;
int parent[VNUM];
int d[VNUM];/*描述从S到V的最短路径上权值的上界---最短路径估计*/
/** 最小优先队列描述**********/
int heap_size=VNUM;
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void min_heaplfy(int *a,int i)
{//使以i为根的子树成为最小堆
int left=LEFT(i);
int right=RIGHT(i);
int smallest=0;
if (left<=heap_size && d[a[left]] < d[a[i]])
smallest=left;
else
smallest=i;
if (right<=heap_size && d[a[right]] < d[a[smallest]])
smallest=right;//select a smallest element
if (smallest!=i)
{
swap(&a[i],&a[smallest]);
min_heaplfy(a,smallest);
}
}
void build_min_heap(int *a)
{//对每一个非叶子结点都调用一次min_heaplfy
int i=0;
for (i=heap_size/2;i>=1;i--)
{
min_heaplfy(a,i);
}
}
int heap_extract_min(int *a)
{//去掉并返回A中具有最小关键字的元素
int min=0;
if (heap_size<1)
printf("heap underflow!/n");
min=a[1];
a[1]= a[heap_size];
heap_size-=1;
min_heaplfy(a,1);
return min;
}
/************************************************************************/
void initialize_single_source(edge *list, int *head, int s)
{/*对最短路径估计和前趋进行初始化*/
int v=0;
for (; v<VNUM; v++)
{
d[v]=MAX_DIST;
parent[v]=NIL;
}
d[s]=0;
}
void relax(int u, int v, int w)
{//测试是否可以通过U,对迄今找到的到V的最短路径进行改进
if (d[v] > (d[u]+w))
{
d[v] = d[u]+w;
parent[v] =u;
}
}
void printpath(int source,int dest)
{
int path[VNUM],i=0;
if (parent[dest]==NIL)
{
printf("no path from %d to %d exists!",source,dest);
}
while (dest!=NIL)
{
path[i]=dest;//记录路径中的顶点
dest=parent[dest];
i++;
}
for (i=i-1; i>=1; i--)
{
printf(" %d-->",path[i]);
}
printf("%d:",path[i]);
}
void print_all_path(int source)
{//打印出所有的从source到其他顶点的最短路径
int i=0;
printf("the minimum paths figured out by dijkstra algorithm are follows:/n");
for (i=1; i<VNUM; i++)
{
printpath(source,i);
printf(" %d/n",d[i]);
}
}
void dijkstra(edge *list,int *head, int s)
{
int Q[VNUM+1]={0,0,1,2,3,4};//下标为0的元素不使用,后面的元素表示每个顶点
initialize_single_source(list,head,s);//initialize
build_min_heap(Q);//建立一个最小堆,key为d[Q[i]]
while (heap_size>0)
{//heap_size表示Q中有效元素的个数,Q[0]不予使用
int i,current;
current=heap_extract_min(Q);//将关键字最小的顶点出列
for (i=head[current]; i<head[current+1]; i++)
{//对current关联的每个顶点进行松弛处理
relax(current,list[i].v,list[i].w);
}
build_min_heap(Q);//rebuild minimum heap by the key "d"
}
}
int main()
{
edge list[11]={ {1,10},{3,5},
{2,1},{3,2},
{4,4},
{1,3},{2,9},{4,2},
{0,7},{2,6}};
int head[VNUM+1]={0,2,4,5,8,10};
dijkstra(list,head,0);
print_all_path(0);
return 0;
}
- Dijkstra算法
- dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra 算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra 算法
- Dijkstra 算法
- dijkstra算法
- Dijkstra 算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- dijkstra算法
- 面试时的“规矩”
- 教你揣摩面试考官心理
- 精简思路后的大写金额转换代码
- MSSQL查找进程造成死锁_把这个进程杀掉
- 我眼中的香港与香港人
- dijkstra算法
- NAC网络准入--整个初始化过程
- 是什么决定了n层架构
- 理解SQLSERVER中的排序规则,解决无法正确显示中文字
- 给右键菜单添加“复制 到文件夹”和“移动到文件夹“选项
- 很黄很暴力
- 学习数据库:SqlServer 2005之数据导出注意事项
- CONVERT 函数 [数据类型转换]
- 纯SQL语句循环查询