第一步
状态 | 已知距离 | 上游 | |
A | 已知 | 0 | A |
C | 邻接 | 1 | A |
D | 邻接 | 6 | A |
E | 邻接 | 9 | A |
P | 未知 | 无穷 |
第二步
状态 | 已知距离 | 上游 | |
A | 已知 | 0 | A |
C | 已知 | 1 | A |
D | 邻接 | 6 | A |
E | 邻接 | 9 | A |
P | 邻接 | 4 | C |
第二步
状态 | 已知距离 | 上游 | |
A | 已知 | 0 | A |
C | 已知 | 1 | A |
D | 邻接 | 6 | A |
E | 邻接 | 7 | P |
P | 已知 | 4 | C |
第三步
状态 | 已知距离 | 上游 | |
A | 已知 | 0 | A |
C | 已知 | 1 | A |
D | 已知 | 6 | A |
E | 邻接 | 7 | P |
P | 已知 | 4 | C |
最后,E成为已知。倒退,可以知道路径为E, P, C, A。正过来,就是从A到E的最短路径了。
----------------------------------------------------------------------------------------------------------------------------------------注解:不断的把未知变已知,从邻接中选取最小的。如上图中的第二步有两个,一个是P未知变邻接,然后重新看距离,到D的距离是此次的最短距离6(A到P的距离反而为7),更新D为已知点。
#include <stdio.h>
#include <stdlib.h>
#define NUM_V 5
#define INFINITY 10000
typedef struct node *position;
typedef struct record *label;
/* node */
struct node {
int element;
position next;
int weight;
};
/* table element, keep record */
struct record {
int status;
int distance;
int previous;
};
/*
* operations (stereotype)
*/
void insert_edge(position, int, int, int);
void print_graph(position, int);
int new_neighbors(position, label, int, int);
void shortest_path(position, label, int, int, int);
/* for testing purpose */
void main()
{
struct node graph[NUM_V];
struct record records[NUM_V];
int i;
// initialize the vertices
for(i=0; i<NUM_V; i++) {
(graph+i)->element = i;
(graph+i)->next = NULL;
(graph+i)->weight = -1;
}
// insert edges
insert_edge(graph,0,1,1);
insert_edge(graph,0,2,6);
insert_edge(graph,0,3,9);
insert_edge(graph,1,4,3);
insert_edge(graph,4,3,3);
print_graph(graph,NUM_V);
// initialize the book
for (i=0; i<NUM_V; i++){
(records+i)->status = -1;
(records+i)->distance = INFINITY;
(records+i)->previous = -1;
}
shortest_path(graph, records, NUM_V, 0, 3);
//
}
void shortest_path(position graph, label records, int nv, int start, int end) {
int current;
(records+start)->status = 1;
(records+start)->distance = 0;
(records+start)->previous = 0;
current = start;
while(current != end) {
current = new_neighbors(graph, records, nv, current);
}
while(current != start) {
printf("%d <- ", current);
current = (records+current)->previous;
}
printf("%d\n", current);
}
int new_neighbors(position graph, label records, int nv, int current) {
int newDist;
int v;
int i;
int d;
position p;
// update the current known
(records + current)->status = 1;
// UPDATE new neighbors
p = (graph+current)->next;
while(p != NULL) {
v = p->element;
(records + v)->status = 0;
newDist = p->weight + (records + current)->distance;
if ((records + v)->distance > newDist) {
(records + v)->distance = newDist;
(records + v)->previous = current;
}
p = p->next;
}
// find the next known
d = INFINITY;
for (i=0; i<nv; i++) {
if ((records + i)->status==0 && (records + i)->distance < d){
d = (records + i)->distance;
v = i;
}
}
return v;
}
/* print the graph */
void print_graph(position graph, int nv) {
int i;
position p;
for(i=0; i<nv; i++) {
p = (graph + i)->next;
printf("From %3d: ", i);
while(p != NULL) {
printf("%d->%d; w:%d ", i, p->element, p->weight);
p = p->next;
}
printf("\n");
}
}
/*
* insert an edge
* with weight
*/
void insert_edge(position graph,int from, int to, int weight)
{
position np;
position nodeAddr;
np = graph + from;
nodeAddr = (position) malloc(sizeof(struct node));
nodeAddr->element = to;
nodeAddr->next = np->next;
nodeAddr->weight = weight;
np->next = nodeAddr;
}
参考文章:http://www.cnblogs.com/vamei/p/3604629.html