2019独角兽企业重金招聘Python工程师标准>>>

#include <iostream>
#include <queue>
#include <map>
#include <stdexcept>//用于抛出异常.
#include <initializer_list> //std::initializer_list
namespace{ //用命名空间还是好的,防止命名污染. static int MAXVALUE = 999;
}
template<typename T>
struct Node{T node_;int weighting_; //weighting_设置的是当前结点到给定源结点的所有的加权值的和默认都被设置为::MAXVALUE. using node_type = T;Node()=default;template<typename Ty>Node(const Ty& node, const int& weighting=0); //构造函数. template<typename Ty>Node(Node<Ty>&& otherNode); //移动构造函数.Node(const Node<T>& otherNode); //拷贝构造函数.Node<T>& operator=(const Node<T>& otherNode); template<typename Ty>friend bool operator<(const Node<Ty>& first_, const Node<Ty>& second);template<typename Ty>friend bool operator==(const Node<Ty>& first_, const Node<Ty>& second_);template<typename Ty>friend std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_);~Node()=default;//注意这里只是设置了默认构造函数
};
template<typename T>
template<typename Ty>
Node<T>::Node(const Ty& node, const int& weighting):node_(node),weighting_(weighting)
{//
}
template<typename T>
template<typename Ty>
Node<T>::Node(Node<Ty>&& otherNode):node_(otherNode.node_),weighting_(otherNode.weighting_)
{//std::cout<<"move-constructor"<<std::endl;
}
template<typename T>
Node<T>& Node<T>::operator=(const Node<T>& otherNode)
{this->node_ = otherNode.node_;this->weighting_ = otherNode.weighting_;//std::cout<<"operator="<<std::endl;return *this;
}
template<typename T>
Node<T>::Node(const Node<T>& otherNode):node_(otherNode.node_),weighting_(otherNode.weighting_)
{//std::cout<<"copy for constructing"<<std::endl;
}
template<typename Ty>
bool operator<(const Node<Ty>& first_, const Node<Ty>& second_) //注意这里因为std::map是有序的切不重复容器.
{return (first_.node_ < second_.node_) ? true : false;
}
template<typename Ty>
bool operator==(const Node<Ty>& first_, const Node<Ty>& second_)
{return (first_.node_ == second_.node_) ? true : false;
}
template<typename Ty>
std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_){os<<node_.node_;return os;
}
class Compare{public:template<typename Ty>bool operator()(const Node<Ty>& first_, const Node<Ty>& second_);
};
template<typename Ty>
bool Compare::operator()(const Node<Ty>& first_, const Node<Ty>& second_)
{return first_ < second_;
}
template<typename T>
class Graph{ //所有边的加权值必须为正. private:std::map<Node<T>, std::map<Node<T>, int>> edges_; //存储无向图的各个边的加权值. std::map<Node<T>, std::vector<Node<T>>> adjList_; //每个结点所相接的结点的邻接链表.  std::map<Node<T>, bool> sourceArray_; //判断该点是否已经被放到了verticeArry_中. std::map<Node<T>, int> dist_; //源结点到每个结点的距离. std::map<Node<T>, Node<T>> node_to_node_;template<typename Ty>void initializer_distance(const Node<Ty>& source_)noexcept;public:template<typename Ty, unsigned int N>Graph(const Ty (&edges)[N][3]); template<typename Ty>void Dijstra(const Ty& node_data);//Dijstra算法. void print()const noexcept;~Graph();
};
template<typename T>
template<typename Ty, unsigned int N>
Graph<T>::Graph(const Ty (&edges)[N][3])
{if(N == 0){std::runtime_error("There is nothing in Graph.\n");}for(int i=0; i<N; ++i){Node<Ty> first_(edges[i][0], ::MAXVALUE);//这里之所以用::因为MAXVALUE位于匿名的namespace中.Node<Ty> second_(edges[i][1], ::MAXVALUE);//每个结点当前的加权值被设置为MAXVALUE. Node<Ty> temp_first_(edges[i][0], ::MAXVALUE);if(edges[i][2] < 0){throw std::runtime_error(std::string("The weighting must be bigger than 0"));}this->adjList_[first_].push_back(second_); //邻接链表. this->dist_[first_] = ::MAXVALUE;this->dist_[second_] = ::MAXVALUE;this->sourceArray_[first_] = false;this->sourceArray_[second_] = false;for(int j=0; j<N; ++j){ //注意下面这几行这是为了构造一个结点的矩阵. 即每个结点与其他结点的之间的权重. Node<Ty> temp_second_(edges[j][0], ::MAXVALUE);if(temp_first_ == temp_second_){this->edges_[temp_first_][temp_second_] = 0;continue;}this->edges_[temp_first_][temp_second_] = ::MAXVALUE;}this->edges_[first_][second_] = edges[i][2];}std::cout<<"out of constructor."<<std::endl;
}
template<typename T>
template<typename Ty>
void Graph<T>::Dijstra(const Ty& node_data)
{std::cout<<"enter dijstra"<<std::endl;Node<Ty> source(node_data);int node_number = this->adjList_.size();this->initializer_distance(source); //获得从source到与source相接的结点的值.for(int i=1; i<node_number; ++i){ //给定的图中一共有node_number个结点. 除去自身因此只需要循环node_number-1次. Node<Ty> temp_node = source;int temp_distance = ::MAXVALUE;typename std::map<Node<Ty>, std::vector<Node<Ty>>>::const_iterator iter_first_ = this->adjList_.cbegin();for(; iter_first_ != this->adjList_.cend(); ++iter_first_){ //这个循环访问图中的每一个结点与给定的源结点 保存当前邻接点中距离最小的一个结点. if(this->sourceArray_[iter_first_->first] == false && this->dist_[iter_first_->first] < ::MAXVALUE){temp_node = iter_first_->first;temp_distance = this->dist_[iter_first_->first];}}this->sourceArray_[temp_node] = true; //把已经找到的结点标记为true,标明已经访问过了. //松弛操作. typename std::map<Node<Ty>, std::vector<Node<Ty>>>::const_iterator iter_second_ = this->adjList_.cbegin();for(; iter_second_ != this->adjList_.cend(); ++iter_second_){ //利用松弛操作,更新temp_node与其他各个结点之间权重. if(this->sourceArray_[iter_second_->first] == false && this->edges_[temp_node][iter_second_->first] < ::MAXVALUE){if(this->dist_[temp_node] + this->edges_[temp_node][iter_second_->first] < this->dist_[iter_second_->first]){this->dist_[iter_second_->first] = this->dist_[temp_node] + this->edges_[temp_node][iter_second_->first];this->node_to_node_[iter_second_->first] = temp_node;}}}}}
template<typename T>
template<typename Ty>
void Graph<T>::initializer_distance(const Node<Ty>& source_)noexcept
{typename std::vector<Node<Ty>>::const_iterator iter_ = this->adjList_[source_].cbegin();for(; iter_ != this->adjList_[source_].cend(); ++iter_){ //dist_记录从source_到图中每个结点的距离.如果这两个结点没有相连接或者只有单向连接那么距离先被设置为::MAXVALUE; this->dist_[*iter_] = this->edges_[source_][*iter_];this->node_to_node_[*iter_] = source_; //把邻接source的结点都放到node_to_node中. }this->dist_[source_] = 0;this->sourceArray_[source_] = true;}
template<typename T>
Graph<T>::~Graph()
{if(!this->edges_.empty()){this->edges_.clear();}if(!this->adjList_.empty()){typename std::map<Node<T>, std::vector<Node<T>>>::iterator iter = this->adjList_.begin();for(; iter!=this->adjList_.end(); ++iter){iter->second.clear();}this->adjList_.clear();}if(!this->sourceArray_.empty()){this->sourceArray_.clear();}if(!this->dist_.empty()){this->dist_.clear();}if(!this->node_to_node_.empty()){this->node_to_node_.clear();}
}
template<typename T>
void Graph<T>::print()const noexcept
{typename std::map<Node<T>, Node<T>>::const_iterator iter = this->node_to_node_.cbegin();for(; iter != this->node_to_node_.cend(); ++iter){std::cout<<iter->first<<"    "<<iter->second<<std::endl;}
}
int main()
{int undirectedGraph[9][3]={ {1, 6, 14}, {1, 3, 9}, {2, 3, 10}, {2, 4, 15}, {3, 6, 2}, {3, 4, 11}, {4, 5, 6}, {5, 6, 9}, {6, 9, 5} };Graph<int> myGraph(undirectedGraph);myGraph.Dijstra(1);myGraph.print();return 0;
}

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/607688

Dijkstra算法.相关推荐

  1. [C] Dijkstra算法——通过边实现松弛

    Dijkstra算法--通过边实现松弛 本算法学习指定一个点(源点)到其余各个顶点的最短路径,也叫做单源最短路径例如求下图1号顶点到2,3,4,5,6号顶点的最短路径 这个时候你可能就要问了,为什么不 ...

  2. 经典算法研究系列:二、Dijkstra 算法初探

    经典算法研究系列:二.Dijkstra 算法初探  July   二零一一年一月 ====================== 本文主要参考:算法导论 第二版.维基百科. 写的不好之处,还望见谅. 本 ...

  3. 贪心算法单源点最短路径例题c语言源代码,Dijkstra算法是解单源最短路径问题的一个贪心算法...

    问题描述 给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数. 另外,还给定 V 中的一个项点,称为源. 现在我们要计算从源到所有其他各项点的最短路径长度. 这里的长度是指路上各边权之 ...

  4. 数据结构与算法(7-4)最短路径(迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)

    目录 一.最短路径概念 二.迪杰斯特拉(Dijkstra)算法(单源最短路径) 1.原理 2.过程 3.代码 三.弗洛伊德(Floyd)算法(多源最短路径) 1.原理 2.存储 3.遍历 4.代码 参 ...

  5. 【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)

    Dijkstra算法是用来求解从某个源点到其他各顶点的最短路径(单源最短路径). 下面的Dijkstra算法的讲解都是基于这个有向图,在遇到其他问题可以类比. 算法的基本思想: 把图中的定点分成两组, ...

  6. 拿来就能用!Dijkstra 算法实现快递路径优化

    作者 | 李秋键 责编 | 伍杏玲 出品 | AI科技大本营(ID:rgznai100) 近几年来,快递行业发展迅猛,其中的程序设计涉及到运送路径的最优选择问题,下面我们尝试模拟实现快递路径优化问题, ...

  7. 基于Dijkstra算法的武汉地铁路径规划!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:牧小熊,华中农业大学,Datawhale原创作者 前言 最近爬取了 ...

  8. 【路径规划】Dijkstra算法——超详细原理图解

    Dijkstra算法详解 1. Dijkstra算法原理  1.1. 有向图的Dijkstra算法  1.2. 无向图和栅格网络的拓展   1.2.1. 无向图   1.2.2. 栅格网络 2. Di ...

  9. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

  10. 【Dijkstra算法】未优化版+优先队列优化版

    https://blog.csdn.net/YF_Li123/article/details/74090301 Dijkstra算法伪代码://G为图:数组d为源点到达各点的最短路径长度,s为起点 D ...

最新文章

  1. 记录一次大对象导致的Java堆内存溢出问题
  2. 利用 50 行 Python 代码构建一个在线文本生成器!
  3. anaconda r 语言_Centos7系统下R、 Rstudio及sparklyr的安装与配置
  4. 不同网段windows远程linux桌面,实现不同网段pc机及交换机互通
  5. C/C++结构体语法总结
  6. 冰雪大作战服务器响应超时,《冰雪大作战》一场回归童心的战争游戏
  7. 如何在Linux系统下配置JDK环境变量
  8. Ubuntu系统安装及su安装
  9. 北京地铁,把什么丢了?
  10. P3265 [JLOI2015] 线性基
  11. 鲸发卡11.02免授权版本
  12. 三极管电路必懂的几种分析方法
  13. Win11系统默认英文字体怎么修改成为中文
  14. openssl之C++实现私(公)钥生成、转换
  15. 正弦波振荡电路的相关概念
  16. 360无线网卡linux,求助,无线网卡快被搞疯了。360wifi2代
  17. 犀牛视频下载器丨钜惠惊喜不断
  18. 判断花心男人的几种方法*转载)
  19. 物联网设备已成大型DDoS攻击马前卒
  20. 知识图谱发展报告(2018)笔记/思维导图

热门文章

  1. 统计数据库中所有表的基本信息
  2. 推荐的 PHP 读物列表
  3. 关于 SAP 标准教程编号的说明
  4. 让静态对象来维护你的数据
  5. iOS 关于第三方键盘
  6. Data Lake Analytics + OSS数据文件格式处理大全
  7. ConstraintLayout 全解析
  8. 《HiWind企业快速开发框架实战》(0)目录及框架简介
  9. 聚焦:好手游难筛选的根本原因
  10. python读取配置文件