最短路径

第一步

 状态已知距离上游
A已知0A
邻接1A
D邻接
E邻接
P未知 无穷 

第二步

 状态已知距离上游
A已知0A
已知1A
D邻接
E邻接
P邻接4C

第二步

 状态已知距离上游
A已知0A
已知1A
D邻接
E邻接7P
P已知 4C

第三步

 状态已知距离上游
A已知0A
已知1A
D已知
E邻接7P
P已知 4C

最后,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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值