数据结构 笔记:最短路劲

最短路劲的概念

如果从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路劲不止一条,那么如何找到一条路径不止一条,那么如何找到一条路径使得此路径各边上的权值总和达到最小?

问题的提法:

-给定一个带权有向图G与起始顶点v,求从v到G中其他顶点的最短路径(每条边上都存在有意义的权值)

解决思路

-Dijkstra提出按路径长度的递增次序,逐步产生最短路径

·首先求出长度最短的一条最短路径,在参照它求出长度次短的一条最短路径,依次类推,知道从起始顶点v到其他各顶点的最短路径全部求出为止

准备工作

-辅助数组:Array<E> dist;

·dist[i]表示当前从起始顶点V0到顶点Vi的路径长度

-初始设置

·若从起始顶点V0到顶点Vi有边:dist[i]为该边上的权值

·若从起始顶点V0到顶点Vi无边:dist[i]为∞

Dijkstra算法步骤

①初始化:S←{V0 }

  dist[j]←Edge[0][j],j=1,2,...,n-1;

②找出最小路径值所对应的顶点K:

  dist[k] == min{dist[i] },i∈V-S;

  S←SU{k};标记k顶点进入S集合

③对于每一个i∈V-S修改:

  dist[i]←min{ dist[i], dist[k] + Edge[k][i] }

④判断:若S = V,则算法结束,否则转②

Dikstra算法精髓

-S集合内的顶点是已经找到最短路径的顶点

-V0到w的最短路径只能通过S集合的顶点

 -dist[w]可能改变:

if(dist[u] + Edge[u,w] < dist[w])
{
    dist[w] = dist[u] + Edge[u,w];
}

定义辅助数组:

-Array<int> path;

·path[i]表示当前路径上顶点i的前驱顶点

·初始化:path = { -1 };

·修改:

if(dist[u] + Edge[u,w] < dist[w])
{
    dist[w] = dist[u] + Edge[u,w];
    path[w] = u;
}

SharedPointer<Array<int> > dijkstra(int i,int j,const E& LIMIT)
    {
        LinkQueue<int> ret;

        if((0 <= i) && (i < vCount())  && (0 <= j) && (j<vCount()))
        {
            DynamicArray<E> dist(vCount());
            DynamicArray<int> path(vCount());
            DynamicArray<bool> mark(vCount());

            for(int k = 0;k<vCount() ;k++)
            {
                mark[k] = false;
                path[k] = -1;

                dist[k] = isAdjacent(i,k) ? (path[k]=i,getEdge(i,k)) : LIMIT;
            }

            mark[i] = true;

            for(int k = 0;k<vCount();k++)
            {
                E m = LIMIT;
                int u = -1;

                for(int w = 0;w < vCount() ; w++)
                {
                    if(!mark[w] && (dist[w] < m))
                    {
                        m = dist[w];
                        u = w;
                    }
                }

                if(u == -1)
                {
                    break;
                }

                mark[u] = true;

                for(int w = 0;w<vCount() ; w++)
                {
                    if(!mark[w] && isAdjacent(u,w) && (dist[u] + getEdge(u,w) < dist[w]))
                    {
                        dist[w] = dist[u] + getEdge(u,w);
                        path[w] = u;
                    }
                }
            }
            LinkStack<int> s;

            s.push(j);

            for(int k = path[j];k!=-1;k=path[k])
            {
                s.push(k);
            }

            while(s.size() > 0)
            {
                ret.add(s.top());

                s.pop();
            }
        }
        else
        {
            //抛出异常
        }

        if(ret.length() < 2)
        {
            //抛出异常
        }
        return toArray(ret);
    }

总结:

-Dijkstra最短路径算法是基于递推的思想完成

-起始顶点到其他各顶点的最短路径通过动态推导得到

-未标记顶点的最短路径只能由已标记顶点计算得出

-算法的最终结果是起始顶点到其他各顶点的最短路径

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值