有向图中Dijstra最短路径算法的邻接表实现

来源:互联网 发布:mp4加速播放软件 编辑:程序博客网 时间:2024/04/29 13:09

网上和书本上很多Dijstra算法的邻接矩的实现,但是对于稀疏图,邻接矩实现方法产生了很多不必要的开销。故此,采用邻接表实现较为合适。

首先将图转换为邻接表表示,本人并没有做传统意义的邻接表,而是用的点索引其出度边。

有向图用例

第一步:图的处理:

建立4个vector数据结构去存储4个顶点的出度,建立边的数据结构存储边的信息.例:

struct edge{   int id;   int from;   int to;   int weight;};vector<int> node[0] = [0,1,2];

第二步:初始化:

node konwn dis(无穷大的数) pre 0 false 100000 -1 1 false 100000 -1 2 false 100000 -1 3 false 100000 -1

node为点的编号
known为到该点的最短路径是否已知
dis为起点到该点的最短路径
pre为引起该点dis变化的最后一个node的编号
代码示例:

struct Station{    int id;    bool known;    int dir;    int pre;    friend bool operator<(Station a,Station b)    {        return a.dir > b.dir;    }};Station node_station[node_num];for(int i=0;i<=node_num;i++)  {    node_station[i].id = i;    node_station[i].known = false;    node_station[i].dir = max_num;//本例设为100000    node_station[i].pre = -1;  }

第三步:算法实现

vector<int>  Digstra_zheng_weigh(int start_p,int end_p,vector<int>* node_temp){    for(int i=0;i<=max_node_num;i++)    {        node_station[i].id = i;        node_station[i].known = false;        node_station[i].dir = max_num;        node_station[i].pre = -1;    }    priority_queue<Station> q;//点的状态的优先队列    node_station[start_p].dir = 0;//起点到起点的距离为0    node_station[start_p].known =true;//起点设为已知    q.push(node_station[start_p]);//起点压进队列    while(!q.empty())    {        Station this_p = q.top();//当前计算起始点        q.pop();//该点已经使用,出队列        int u = this_p.id;//该点的id        if(node_station[u].known) //如果该点已经已知,下一个              continue;        node_station[u].known = true;//该点设为已知        vector<int> edge_temp = node_temp[u];//当前节点的出度<边>        for(int j=0;j<edge_temp.size();j++)        {            int id_n = edge_point[edge_temp[j]].to;            if(!node_station[id_n].known && node_station[id_n].dir > node_station[u].dir + edge_point[edge_temp[j]].weight )            {                node_station[id_n].dir = node_station[u].dir + edge_point[edge_temp[j]].weight;                node_station[id_n].pre = u;                q.push(node_station[id_n]);            }        }    }    vector<int> out;    out.clear();    if(node_station[end_p].known)    {        int n = end_p;        while(node_station[n].pre != -1)        {            //out.insert(out.begin(),n);            n = node_station[n].pre;            out.insert(out.begin(),n);        }        if(node_station[end_p].known)            this_route_weight += node_station[end_p].dir;        //out.insert(out.begin(),n);    }    return out;}

简述算法流程:

Dijstra(int start,vector<int> node){   1、init_node_station();//初始化所有点的状态   2、start点的dis设为0,known设为true;将所有start点能到的点的dis设为对应边的权重,pre设为start while(1){   取所有dis中最短的点P设为新的起点,如果该点的known为true,退出循环;否则,将该点known设为true,   判断P点能到达的点M[i],       if(!station[M[i].known)          if(station[M[i].dis > station[P].dis +  该边的权重)          {             station[M[i]].dis = station[P].dis +  该边的权重             station[M[i]].pre = P          }    }}//这时,若该点的known为true,则该点的dis为起点到该点的最短距离
0 0