Dijkstra算法 学习笔记

Dijkstra算法最初用于搜索一个正加权连通图中两顶点(起始点, 终点)之间最短路径。 它由Edsger W. Dijkstra 在1956设计,并于三年后发表[wiki].
Dijkstra[3]Dijkstra[3]

算法核心思想

将图中顶点分为两个集合,一个集合 S S S包含已搜索过的顶点; 另一个集合 S ∗ S^{*} S S S S的补集, 包含未搜索过的顶点.
以顶点到起始点之间最短路径为度量,为 S S S中各顶点赋值.
基于 S S S边界逐步向 S ∗ S^{*} S扩展, 直到搜索到终点为止.

Dijkstra算法适用范围

  • 连通图。
  • 图中边的加权值应为正数。

算法实现

Dijkstra算法的实现需要两种容器类数据结构: 一个是维护图信息,另一个保存路径信息. Dijkstra算法所需的图操作有:

  • 添加顶点,添加边,
  • 设置边的权值,
  • 提取顶点,
  • 遍历与某个顶点相连的边和顶点.

代码

Rosetta提供了一个C语言版的Dijkstra算法代码[Rosetta]. 现将其改写成C++版, 代码如下:

dijkstra.h

#ifndef YANG_A_GRAPH_DIJK_H_
#define YANG_A_GRAPH_DIJK_H_
/*
 * dijkstra.h
 *
 *  Created on:
 *      Author:
 *  Based on:
 *  https://rosettacode.org/wiki/Dijkstra%27s_algorithm
 *
 *  Copyright @ 2017. CHUNFENG YANG. All Rights Reserved.
 *  Permission to use, copy, modify, and distribute this software
 *  and its documentation for educational, research, and
 *  not-for-profit purposes, without fee and without a signed
 *  above copyright notice, this paragraph and the following two
 *  distributions.
 *  IN NO EVENT SHALL CHUNFENG YANG BE LIABLE TO ANY PARTY FOR
 *  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
 *  DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
 *  SOFTWARE AND ITS DOCUMENTATION, EVEN IF CHUNFENG YANG HAS BEEN
 *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  CHUNFENG YANG SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 *  BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *  AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
 *  ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS
 *  PROVIDED "AS IS". CHUNFENG YANG HAS NO OBLIGATION TO PROVIDE
 *  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

class Edge
{
public:
	Edge();
	virtual ~Edge();

public:
	void show();

public:
	int _vertex;
	double _weight;
};

class Vertex
{
public:
	Vertex();
	virtual ~Vertex();
public:
	void addEdge(Edge*);
	void setDist(double);
	double getDist();
	void setPrev(int);
	int getPrev();
	void setVisited(int);
	int getVisited();
	int edgeLength();
	Edge* getEdge(int);

	void show();
public:
	Edge **_edges;
	int _edges_len;
	int _edges_size;
	double _dist;
	int _prev;
	int _visited;
};



class Heap
{
public:
	Heap();
	Heap(int n);
	virtual ~Heap();

public:
	void push(int v, double p);
	int pop();
	int minimize(int i, int j, int k);
	int length();
	void show();
	void clean();
public:
	int *_data;
	double *_prio;
	int *_index;
	int _len;
	int _size;
};

class Graph
{
public:
	Graph();
	virtual ~Graph();

	Graph(int);

public:
	void addVertex(int i);
	void addEdge(int a, int b, double w);
	void dijkstra(int a, int b);

	void print_path(int);

	void show();

	double distance(int i, int j);
	int length();
public:
	Vertex **_vertices;
	int _vertices_len;
	int _vertices_size;
};

#endif // YANG_A_GRAPH_DIJK_H_

dijkstra.cc

/*
 * dijkstra.cc
 *
 *  Created on:
 *      Author:
 *  Based on:
 *  https://rosettacode.org/wiki/Dijkstra%27s_algorithm
 *
 *  Copyright @ 2017. CHUNFENG YANG. All Rights Reserved.
 *  Permission to use, copy, modify, and distribute this software
 *  and its documentation for educational, research, and
 *  not-for-profit purposes, without fee and without a signed
 *  above copyright notice, this paragraph and the following two
 *  distributions.
 *  IN NO EVENT SHALL CHUNFENG YANG BE LIABLE TO ANY PARTY FOR
 *  DIRECT, INDIRECT, SPECIAL, INCID
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值