#include <iostream>
#include <queue>
#include <stdexcept> //throw std::runtime_error("xx");
#include <initializer_list>
#include <map>
template<typename T>
struct Edge{
T start_;
T end_;
int weighting_;
Edge()=default;
template<typename Ty>
Edge(const Ty& start, const Ty& end, const int& wg);
template<typename Ty>
Edge(const Edge<Ty>& otherEdge);
~Edge()=default;
};
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Ty& start, const Ty& end, const int& wg)
:start_(start),
end_(end),
weighting_(wg)
{
//
}
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Edge<Ty>& otherEdge)
:start_(otherEdge.start_),
end_(otherEdge.end_),
weighting_(otherEdge.weighting_)
{
//
}
class Compare{ //Compare用于prioprity_queue中的比较参数.
public:
template<typename Ty>
bool operator()(const Ty& first_, const Ty& second_)
{
return first_ < second_ ? true : false;
}
};
template<typename T>
class Graph{
private:
Edge<T>* edgeArray; //store the start-node and end-node, the weighting between start-node and end-node;
std::map<T, bool> visited_; //每个顶点都对应一个bool值, 访问过的话该bool值会被设置为true;
std::map<T, std::vector<T>> edges_; //邻接链表.即,每一个顶点与其他顶点相接,其他顶点都被放在vector<T>中.
std::priority_queue<T, std::vector<T>, Compare> cycle_; //如果该顶点有环路那么吧该顶点放入到cycle_;
std::map<T, bool> haveCycle_; //判断该点时候存在环路.
//std::multimap<T, T> edgeTo_;
std::vector<T> result_;
int edgeNumber_;
bool flag_; //判断该有向加权图中是否存在回路.默认为true;
public:
template<typename Ty>
using iter = typename std::map<Ty, bool>::iterator;
template<typename Ty, unsigned int N>
Graph(const Ty (&edges)[N][3]);
template<typename Ty>
void dfs(const Ty& node_);
void helperFunction();
void print();
~Graph();
};
template<typename T>
template<typename Ty, unsigned int N>
Graph<T>::Graph(const Ty (&edges)[N][3])
:edgeArray(nullptr),
edgeNumber_(N),
flag_(true)
{
if( N == 0 ){
std::runtime_error("The Graph has cycle.\n");
}
this->edgeArray = new Edge<Ty>[N]; //存储有向图的各个条边以及该边的加权值.
for(int i=0; i<N; ++i){ //存储有向加权图,且存储有向加权图的每一个结点.默认都是未被访问过的因此其对应的值为false.
Edge<Ty> edge(edges[i][0], edges[i][1], edges[i][2]);
this->edgeArray[i] = edge;
this->visited_[edges[i][0]] = false;
this->visited_[edges[i][1]] = false;
//this->haveCycle_[edges[i][0]] = false;
//this->haveCycle_[edges[i][1]] = false;
this->edges_[edges[i][0]].push_back(edges[i][1]); //邻接链表.即每个结点与其他结点相接,其他结点都被放在与该结点对应的std::vector中.
}
std::cout<<"out of constructor fucntion"<<std::endl;
/*iter<Ty> it = this->haveCycle_.begin();
for(; it!=this->haveCycle_.end(); ++it){
std::cout<<it->first<<std::endl;
}*/
}
template<typename T>
template<typename Ty>
void Graph<T>::dfs(const Ty& node_) //该算法是基于深度优先遍历的.
{
std::cout<<"node: "<<node_<<std::endl;
this->visited_[node_] = true; //当前结点已经被访问.把其对应的属性设置为true;
this->haveCycle_[node_] = true; //haveCycle_是一个存放具有环路结点的容器.
int temp = this->edges_[node_].size(); //获得与该结点相接的结点的个数.
for(int i=0; i<temp; ++i){
if( !this->flag_ ){
return;
}
if( !this->visited_[this->edges_[node_][i]] ){
//this->edgeTo_[this->edges_[node_][i]] = node_;
this->dfs(this->edges_[node_][i]);
}else if(this->haveCycle_[this->edges_[node_][i]]){
this->flag_ = false;
std::cout<<"have cycle"<<std::endl;
this->cycle_.push(node_);
this->cycle_.push(this->edges_[node_][i]);
}
}
this->result_.push_back(node_);
this->haveCycle_[node_] = false;
}
template<typename T>
void Graph<T>::helperFunction()
{
Graph<T>::iter<T> it = this->visited_.begin();
for(; it != this->visited_.end(); ++it){
if( !this->visited_[it->first] ){
this->dfs(it->first);
}
}
}
template<typename T>
void Graph<T>::print()
{
if( !this->flag_ ){
std::cout<<"failed"<<std::endl;
}else{
std::cout<<"successful"<<std::endl;
Graph<T>::iter<T> it = this->haveCycle_.begin();
for(; it!=haveCycle_.end(); ++it){
std::cout<<it->first<<std::endl;
}
}
}
template<typename T>
Graph<T>::~Graph()
{
if(this->edgeArray != nullptr ){
delete[] edgeArray;
}
if( !this->visited_.empty() ){
this->visited_.clear();
}
if( !this->edges_.empty() ){
this->edges_.clear();
}
if( !this->haveCycle_.empty() ){
this->haveCycle_.clear();
}
}
int main()
{
int edge[][3]={ {0,2, 6}, {0,6, 6}, {2,6, 7}, {2,5, 4}, {2,4, 2}, {6,5 -1}, {6,4, 1}, {5,4, -2}};
Graph<int> myGraph(edge);
myGraph.helperFunction();
myGraph.print();
return 0;
}