data structure最短路径问题

1.问题引入


现在人们出行用滴滴就特别方便。在滴滴上我们打到车后在司机的手机上就会选择到目的地最短的一条路径。那在软件中这个最短的路径是怎么产生的呢?
这儿就来介绍产生最短路径的两种方法:
Dijkstra 和Floyd

最短路径:源点到终点的距离最短的路径(在这儿体现为: 源点到终点路径上边的权值之和)

Dijkstra 和Floyd

这两个算法及其相似;
我自己将它门分别归为二维操作和三维操作。


S 集合:已经求出的最短路径顶点集合

Dijkstra的最短路径推导过程中:
1. 先找到起点
2. 然后从起点选择到其他顶点的可达路径
3. 然后选择到(除开S集中的顶点)权值最小的路径指向的顶点作为下一步的起点、并且将指向的顶点加入到 已经求出的最短路径顶点集合S里
4. 又到第二步,直到n个结点全部求出


Dijkstra算法:

这是一个单源点算法:单源点就是一个起点的啦!
处理的是:带权有向图
存储:邻接矩阵
思想是:依照路径长度递增的次序来产生最短路径

typedef struct {
    Matrix[][];//邻接矩阵
    vexnum;//顶点数目
    arcnum;//边数目
    type;//矩阵类型
}Graph;
int *Dijkstra_fun(Graph Graph,int begin){
    for(v=0;Graph.vexnum;++v)
    {
        finial[v] = false;//顶点是否在S集合中  S集合(已经求得的最短路径终点集合)
        Distance[v] = Graph.Matrix[begin][v];   //begin是起点
    }
    finial[begin] = true;
    Distance[begin] = 0;//初始化 将begin顶点加入到S集合中   begin顶点到本身路径长度为0
    for(i=1;i<Graph.vexnum;++i)
    {
        min = INT_MAX;
        for(w=0;w<Graph.vexnum;++w)
            if( !finial[w] )//不在S集合中
                if(Distance[w] < min)
                {
                    p =w;//暂存顶点w
                    min = Distance[w]; //该顶点的值赋给最小值 
                }
        finial[w] = true;//w顶点加入到finial中
        for(w=0;w<Graph.vexnum;++w) 
            if(!finial[w] && Distance[w] > ( min + Graph.Matrix[p][w]))
                 Distance[w] = min + Graph.Matrix[p][w];
    }
    return Distance
}

一个例子:
这里写图片描述


Floyd算法:

一对顶点之间的的最短路径处理:
1. Dijkstra算法调用n次 ,T(n) = O(n^3),因为 Dijkstra算法复杂度为O(n^2)
2. Floyd算法

这里写图片描述
针对一对顶点的最短路径计算

for(mid = 0 ; mid < G.vexnum ; ++mid)
    for(front = 0 ; front < G.vexnum ; ++front)
        for(rear = 0 ; rear < G.vexnum ; ++rear)
            if(G.matrix[front][rear] > (G.matrix[front][mid] + G.matrix[mid][rear]))
                G.matrix[front][rear] = G.matrix[front][mid] + G.matrix[mid][rear];
//动态规划思想
//邻接矩阵表示
//可看做G[mid][front][rear]
//G的最外层可省略:因为G[k]只和G[k-1]有关
//G[0]等于最初图的邻接矩阵

未完待续(初稿1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值