Dijikstra算法.

#include <iostream>
#include <queue>
#include <map>
#include <stdexcept>
namespace{
 static int MAXVALUE = 999;
}
template<typename T>
struct Node{
 T node_;
 int weighting_; //weighting_设置的是当前结点到给定源结点的所有的加权值的和默认都被设置为::MAXVALUE. 
 
 using node_type = T;
 
 template<typename Ty>
 Node(const Ty& node, const int& weighting=0); //构造函数. 
 
 template<typename Ty>
 Node(Node<Ty>&& otherNode); //移动构造函数.
 
 template<typename Ty>
 Node(const Node<Ty>& 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_);
 
 ~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>
template<typename Ty>
Node<T>::Node(const Node<Ty>& otherNode)
        :node_(otherNode.onde_),
         weighting_(otherNode.weighting_)
{
 //
 std::cout<<"copy for constructing"<<std::endl;
}
template<typename Ty>
bool operator<(const Node<Ty>& first_, const Node<Ty>& second_)
{
 return (first_.weighting_ < second_.weighting_) ? true : false;
}
template<typename Ty>
bool operator==(const Node<Ty>& first_, const Node<Ty>& second_)
{
 return (first_.node_ == second_.node_) ? true : false;
}
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::priority_queue<Node<T>, std::vector<Node<T>>, Compare> vertices_; //按照各个结点weighting_的大小来进行比较,作为除了给定源点外其他结点的集合. 
  std::vector<Node<T>> verticeArray_; //存储从vertices_中找到最短路径的集合. 
  
  template<typename Ty>
  void relax(const Node<Ty>& first_, const Node<Ty>& second_); //松弛操作. 
  
  
  public:
   template<typename Ty, unsigned int N>
   Graph( const Ty (&edges)[N][3] ); //构造函数. 
   
   template<typename Ty>
   void Dijstra(const Ty& node_data); //Dijstra算法. 
   
   ~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. 
  this->edges_[first_][second_] = edges[i][2]; //设置每条边相对应的加权值. 
  
  this->adjList_[first_].push_back(second_); //与first_相连的顶点被放在与其对应的std::vector中了. 
 }
 
 std::cout<<"out of constructor."<<std::endl;
}
template<typename T>
template<typename Ty>
void Graph<T>::relax(const Node<Ty>& first_, const Node<Ty>& second_)
{
 if(second_.weighting_ > first_.weighting_ + this->edges_[first_][second_]){ //second_为first_的前驱结点. 
  second_.weighting = first_.weighting_ + this->edges_[first_][second_]; //如果前驱结点的weighting_大于当前结点(first_)的weighting_.
  //那么把前驱结点的weighting_设置为当前结点的weighting_和first_跟second_之间加权值的和. 
 }
}
template<typename T>
template<typename Ty>
void Graph<T>::Dijstra(const Ty& node_data)
{
 Node<Ty> source(node_data, 0); //设置源结点. 源结点的weighting_被设置为0. 
  typename std::map<Node<Ty>, std::map<Node<Ty>, int>>::const_iterator iter = this->edges_.cbegin(); //把所有的顶点存储到一个栈. 
  this->verticeArray_.push_back(source); //把原点以及相距原点最短的结点都放入到verticeArray_中. 
  
  for(; iter != this->edges_.end(); ++iter){ //把除了原点外的所有结点都放到vertices_中. 
   
   if(source == iter->first){
    continue;
   }
   this->vertices_.push(iter->first);
  }
  
  if( !this->vertices_.empty() ){
   
   for(int i=0; i<this->vertices_.size(); ++i){ //逐个访问vertices_中的结点. 
    Node<Ty> node = this->vertices_.top();
    this->vertices_.pop();
    this->verticeArray_.push_back(node); //把当前结点放到verticeArray_中. 
    
    for(int j=0; j<this->adjList[node].size(); ++j){ //对于vertices_中各个结点相接的结点进行松弛操作. 
     this->relax(node, this->adjList_[node][j]);
    }
   }
  }
 
}
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->verticeArray_.empty()){
  this->verticeArray_.clear();
 }
 
}
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);
 
 return 0;
}

你可能感兴趣的:(Dijikstra算法.)