Dijkstra — 最短路径算法

本文深入探讨了Dijkstra算法在有向图中搜索最短路径的过程,详细介绍了算法的主要步骤,包括初始化、寻找最小值及更新过程,并通过具体代码实例展示了算法的应用。

Dijkstra算法,狄克斯特拉算法,在有向图中搜索最短路径。

本文实现单个顶点到其余各个顶点之间的最短路径,与Prim算法有很多相似的地方。
算法实现的主要步骤:
(1) 初始化
所有点都初始化为没有被访问,初始化根结点到各结点的距离,存放在lowcost[]数组中;

(2)寻找最小值
从根结点开始,其依据:按照由近到远的次序求解
找到最小值后,更新lowcost[]
更新lowcost[]与Prim算法不同。

(3)重复第(2)步,直到所有点都被选中,则算法结束。

本文依据下图对算法实现:

这里写图片描述

具体代码如下,已经在vs2010测试通过

#include <iostream>
using namespace std;

#define DirectedGraphNode 8
#define INFINITE 1000

void Dijkstra(int directedGraph[][DirectedGraphNode], bool visited[], int lowcost[], int path[])
{
    //初始化
    memset(visited, 0, sizeof(bool) * DirectedGraphNode);
    for(int i = 1; i < DirectedGraphNode; i++)
        lowcost[i] = directedGraph[0][i];
    visited[0] = true;
    path[0] = 0;

    int k = 0;
    int min;
    int minIndex;
    for(int i = 1; i < DirectedGraphNode; i++ )//外循环,每次循环确定一个点
    {
        min = INFINITE;
        //寻找最小值
        for(int j = 1; j < DirectedGraphNode; j++)
        {
            if(false == visited[j] && lowcost[j] < min)
            {
                min = lowcost[j];
                minIndex = j;
            }
        }
        visited[minIndex] = true;//该点被访问
        path[++k] = minIndex;

        //更新lowcost[]
        //lowcost[]为各个结点到根结点的最短距离,从根结点出发,依次到达各结点
        for(int j = 1; j < DirectedGraphNode; j++)
        {
            if(false == visited[j] && lowcost[j] > lowcost[minIndex] + directedGraph[minIndex][j])
                lowcost[j] = lowcost[minIndex] + directedGraph[minIndex][j];
        }
    }
}

void DijkstraRun()
{
    //点与点之间存在边,权重为非零值,非无穷大值
    //点与点之间不存在边,权重为无穷大值
    int directedGraph[][DirectedGraphNode] = 
    {
        {INFINITE, 30, 50, INFINITE, 10, INFINITE, INFINITE, INFINITE},
        {INFINITE, INFINITE, 2, INFINITE, INFINITE, INFINITE, 6, INFINITE},
        {INFINITE, INFINITE, INFINITE, 20, INFINITE, INFINITE, 3, INFINITE},
        {INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, INFINITE},
        {20, 18, INFINITE, INFINITE, INFINITE, 7, INFINITE,  INFINITE},
        {INFINITE, 8, INFINITE, INFINITE, INFINITE, INFINITE, 15, INFINITE},
        {INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, INFINITE, 15},
        {INFINITE, INFINITE, INFINITE, 12, INFINITE, INFINITE, INFINITE, INFINITE},
    };

    bool visited[DirectedGraphNode];
    int path[DirectedGraphNode];
    int lowcost[DirectedGraphNode];

    Dijkstra(directedGraph, visited, lowcost, path);

    cout<<"访问结点的顺序:"<<endl;
    for(int i = 0; i < DirectedGraphNode; i++)
        cout<<"v"<<path[i] + 1<<" ";//v1表示第一个结点
    cout<<endl<<endl;

    cout<<"各个结点到根结点的最短路径值:"<<endl;
    for(int i = 1; i < DirectedGraphNode; i++)
        cout<<lowcost[i]<<" ";
    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    DijkstraRun();
    return 0;
}

算法运行结果如图所示:

这里写图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值