算法学习 - Dijkstra(迪杰斯特拉)算法学习

Dijkstra算法

其实Dijkstra是单源点最短路径的基础算法,这个算法的目的就是找到一个图中的某个点V到这个图中其他点的最短路径。

条件

  • 有向图
  • 没有负权值路径

时间复杂度:O(E) + O(V^2) = O(V^2)

当图是稠密的时候和稀疏的时候时间复杂度还是有点差别的。

代码实现

其实这个还挺简单的,单源点最短路径还有一个Bellman-Ford算法,以后在写,比较简单。

Dijkstra算法:

//
//  main.cpp
//  Dijkstra
//
//  Created by Alps on 15/3/4.
//  Copyright (c) 2015年 chen. All rights reserved.
//

#include <iostream>

#ifndef NumVertex
#define NumVertex 4 //定义图的顶点数量
#endif

#ifndef Infinity
#define Infinity 10000 //定义权值最大值
#endif

using namespace std;

typedef int  Vertex;

struct LinkList{ //定义邻接链表
    int val;
    int length;
    LinkList * next;
    LinkList(int v): val(v), next(NULL) {}
};

typedef LinkList* List;

struct TableEntry{ //定义结构体用来实现算法。
    List Header;
    bool Know;
    int Dist;
    Vertex Path;
};

typedef struct TableEntry Table[NumVertex+1]; //定义结构体所存储的图

void InitTable(Vertex Start, Table T){ //初始化
    List temp;
    int OutDegree;
    for (int i = 1; i <= NumVertex; i++) {
        T[i].Know = false;
        T[i].Dist = Infinity;
        T[i].Path = -1;
        T[i].Header = NULL;
        scanf("%d",&OutDegree);
        for (int j = 0; j < OutDegree; j++) {
            temp = (List)malloc(sizeof(struct LinkList));
            scanf("%d %d",&(temp->val), &(temp->length));
            temp->next = T[i].Header;
            T[i].Header = temp;
        }
    }

    T[Start].Dist = 0;
}

void PrintPath (Vertex V,Table T){ //打印路径
    if (T[V].Path != -1) {
        PrintPath(T[V].Path, T);
        printf(" to ");
    }
    printf("%d", V);
}

Vertex SmallDistUnknow(Table T){ //查找当前已知顶点到未知顶点路径的最小值
    int MinDist = Infinity + 1, V = 0;
    for (int i = 1; i <= NumVertex; i++) {
        if (!T[i].Know && T[i].Dist <= MinDist) {
            MinDist = T[i].Dist;
            V = i;
        }
    }
    return V;
}

void Dijkstra(Table T){ //算法主题
    List temp;
    Vertex V;
    while (1) {
        V = SmallDistUnknow(T);
        if (V == 0) {
            break;
        }
        T[V].Know = true;
        temp = T[V].Header;
        while (temp != NULL) {
            if (!T[temp->val].Know) {
                if (T[V].Dist + temp->length < T[temp->val].Dist) {
                    T[temp->val].Dist = T[V].Dist + temp->length;
                    T[temp->val].Path = V;
                }
            }
            temp = temp->next;
        }
    }
}

int main(int argc, const char * argv[]) {

    Table T;

    InitTable(1, T);

    Dijkstra(T);

    PrintPath(2, T);

//    std::cout << "Hello, World!\n";
    return 0;
}
时间: 2024-11-04 22:12:22

算法学习 - Dijkstra(迪杰斯特拉)算法学习的相关文章

[小明学算法]4.Dijkstra(迪杰斯特拉)算法

1.定义概念 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.值得注意的是,该算法要求图中不存在负权边. 2.基本思想 设置顶点集合S,初始时,S中仅含有起始点,把从起始点到u且中间只经过S中顶点的路称为从起始点到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径的长度.Dijkstra算法每次从S外取出对应dist值最小的节点u,将其添加到S中,并对所有与u点直接相连

Dijkstra迪杰斯特拉算法

迪杰斯特拉算法是用于求解图的单元最短路径问题,即某个源点到达图中其余顶点的最短路径,其核心思想是每次从剩余未归入路径的顶点中找到一个到达当前路径距离最短的顶点,将其归入路径中,共执行n-1次.该算法需要三个辅助数组,s[ ]数组用来标记各个顶点有没有被归入当前路径中,dist[ ]数组用于表示当前源点到达各个顶点的最短路径长度,path[ ]数组用来存储该顶点在最短路径中的前驱结点. #include<stdio.h> //迪杰斯特拉算法,求带权图中某个源点到到达其余各个顶点的最短路劲,其需要

Dijkstra(迪杰斯特拉)算法求解最短路径

过程 首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新.每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离.以这个原则,经过N轮计算就能得到每一个节点的最短距离. 第一轮,可以计算出,2.3.4.5.6到原点1的距离分别为:[7, 9, -1, -1, 14].-1表示无穷大.取其中最小的,为7,即可以确定1的最短路径为0,2为下一轮的前驱节点.同时确定2节点的最短路径为7,路线:1->2. 第二轮,取2节点为前驱节点,按照前驱节点的

hdu 2544 最短路 题解 (dijkstra/迪杰斯特拉算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 这道题用dijkstra模板一套就出来了. 模板:http://blog.csdn.net/xdz78/article/details/47719849 需要注意的是,这里的边应该是双向边,所以在输入边的数据的时候应该这样写: for(i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); g.map[a][b]=g.map[b]

C# 迪杰斯特拉算法 Dijkstra

什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Generic; namespace 算法 { /// <summary> /// Dijkstra /// 迪杰斯特拉算法 /// </summary> public class Dijkstra : ICloneable { /// <summary>节点集合</summa

学习笔记:迪杰斯特拉算法

一.算法概要 1.迪杰斯特拉算法是典型的单源最短路径算法. 2.主要特点是以起始点为中心向外扩展,直到扩展至终点为止. 二.算法步骤 1.将图中的顶点划分为两组,第一组为已求出最短路径的顶点,第二组为未确定最短路径的顶点. 2.初始时,第一组只包含起始点. 3.从第一组中选择最近一次加入的顶点,找到该顶点在第二组中最近的邻接点.以该邻接点为中心点更新各点到起始点的距离,若从起始点经过该邻接点到达任意顶点的距离小于原来的距离,则更新之.若更新则更新的距离为 起始点到邻接点的距离+邻接点到该任意顶点

最短路径算法——迪杰斯特拉算法(Dijkstra)

图结构中应用的最多的就是最短路径的查找了,关于最短路径查找的算法主要有两种:迪杰斯特拉算法(Dijkstra)和Floyd算法. 其中迪杰斯特拉算法(Dijkstra)实现如下: 原理就是不断寻找当前的最优解: void main() { int V[Max][Max]={0,8,32,Infinity,Infinity, 12,0,16,15,Infinity, Infinity,29,0,Infinity,13, Infinity,21,Infinity,0,7, Infinity,Infi

最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等. 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 初始时,S

最短路径之迪杰斯特拉算法(Dijkstra)

1.迪杰斯特拉(dijkstra)算法简介 Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式, 是目前公认的最好的求解最短路径的方法.算法解决的是有向图中单个源点到其他顶点的最短 路径问题,其主要特点是每次迭代时选择的下一个顶点是标记点之外距离源点最近的顶点.但 由于dijkstra算法主要计算从源点到其他所有点的最短路径,所以算法的效率较低. 2.dijkstra算法基本过程 假设路网中每一个节点都有标号 是从出发点s到点t的最短路径长

普里姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛里德算法

做数据结构的课程设计顺便总结一下这四大算法,本人小白学生一枚, 如果总结的有什么错误,希望能够告知指正 普里姆算法如图所示prim 找出最短的边,再以这条边构成的整体去寻找与之相邻的边,直至连接所有顶点,生成最小生成树,时间复杂度为O(n2) 克鲁斯卡尔算法如图所示kruskal 克鲁斯卡尔算法,假设连通网N=(N,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点 自成一个连通分量.在E中选择代价最小的边,若该边依附的定顶点落在T中不同的连通分量上,