diff --git a/TinySTL/Detail/Graph.impl.h b/TinySTL/Detail/Graph.impl.h index 308d01e..146015a 100644 --- a/TinySTL/Detail/Graph.impl.h +++ b/TinySTL/Detail/Graph.impl.h @@ -4,15 +4,15 @@ namespace TinySTL{ namespace Detail{ template typename graph::node& - graph::new_node(const Index& index, const Value& val)const{ + graph::new_node(const Index& index, const Value& val){ auto ptr = nodeAllocator::allocate(); nodeAllocator::construct(ptr, node(index, val)); return *ptr; } template - bool graph::is_contained(const node& n){ + bool graph::is_contained(const Index& index){ for (auto& pair : nodes_){ - if (equal_func(pair.first.first, n.first)) + if (equal_func(pair.first.first, index)) return true; } return false; @@ -22,25 +22,82 @@ namespace TinySTL{ graph::empty_node_set(){ return node_sets(); } + template + bool graph::empty()const{ + return nodes_.empty(); + } + template + typename graph::bucket_iterator + graph::begin(const Index& index){ + for (auto& pair : nodes_){ + if (equal_func(pair.first.first, index)) + return bucket_iterator(this, (pair.second).begin()); + } + return end(index); + } + template + typename graph::bucket_iterator + graph::end(const Index& index){ + for (auto& pair : nodes_){ + if (equal_func(pair.first.first, index)) + return bucket_iterator(this, (pair.second).end()); + } + throw std::exception("return end error"); + } + template + size_t graph::size()const{ + return size_; + } + //******************************************************************************** + template + graph_iterator& graph_iterator::operator ++(){ + ++inner_it_; + //if (inner_it_ == (outter_it_->second).end()){//to end + // ++outter_it_; + // if (outter_it_ != container_->nodes_.end())//not to end + // inner_it_ = (outter_it_->second).begin(); + //} + return *this; + } + template + const graph_iterator graph_iterator::operator ++(int){ + auto temp = *this; + ++*this; + return temp; + } + template + bool operator ==(const graph_iterator& lhs, + const graph_iterator& rhs){ + return lhs.container_ == rhs.container_ && + //lhs.outter_it_ == rhs.outter_it_ && + lhs.inner_it_ == rhs.inner_it_; + } + template + bool operator !=(const graph_iterator& lhs, + const graph_iterator& rhs){ + return !(lhs == rhs); + } }//end of Detail template directed_graph::directed_graph():graph(){} template void directed_graph::add_node(const node& n, const node_sets& nodes){ - if (!is_contained(n)) + if (!is_contained(n.first)){ nodes_.push_front(make_pair(n, list())); + ++size_; + } if (nodes.empty()) return; //find node n's list - list l; + list* l; for (auto& pair : nodes_){ if (equal_func(pair.first.first, n.first)) - l = pair.second; + l = &(pair.second); } for (const auto& item : nodes){ - l.push_front(item); - if (is_contained(item)){ + l->push_front(item); + if (!is_contained(item.first)){ add_node(item, empty_node_set()); } } diff --git a/TinySTL/Graph.h b/TinySTL/Graph.h index bd20c24..84bdb3a 100644 --- a/TinySTL/Graph.h +++ b/TinySTL/Graph.h @@ -6,30 +6,76 @@ #include "Utility.h" #include "Vector.h" +#include + namespace TinySTL{ namespace Detail{ + template + class graph_iterator; template> class graph{ + public: + friend class graph_iterator < Index, Value, EqualFunc >; public: typedef Index index_type; typedef Value value_type; typedef EqualFunc equal_func_type; typedef pair node; typedef vector node_sets; + typedef graph_iterator bucket_iterator; typedef allocator nodeAllocator; + typedef std::function visiter_func_type; public: + graph() :size_(0){}; virtual ~graph(){}; virtual void add_node(const node& item, const node_sets& nodes) = 0; + //virtual void delte_node(const node& item) = 0; + //virtual node_sets adjacent_nodes(const node& n) = 0; + //virtual node_sets adjacent_nodes(const Index& index) = 0; + //virtual void DFS(visiter_func_type func) = 0; + //virtual void BFS(visiter_func_type func) = 0; - node& new_node(const Index& index, const Value& val)const; - bool is_contained(const node& n); + static node& new_node(const Index& index, const Value& val); + bool is_contained(const Index& index); inline static node_sets empty_node_set(); + inline bool empty()const; + inline size_t size()const; + inline bucket_iterator begin(const Index& index); + inline bucket_iterator end(const Index& index); protected: list>> nodes_; equal_func_type equal_func; + size_t size_; + }; + + template> + class graph_iterator{ + public: + friend class graph < Index, Value, EqualFunc > ; + typedef graph* cntrPtr; + typedef graph graph_type; + typedef typename list::iterator inner_it_type; + public: + graph_iterator(cntrPtr c, inner_it_type iit) + :container_(c), inner_it_(iit){} + graph_iterator& operator ++(); + const graph_iterator operator ++(int); + typename graph_type::node& operator*(){ return *inner_it_; } + typename graph_type::node* operator ->(){ return &(operator*()); } + private: + cntrPtr container_; + inner_it_type inner_it_; + public: + template + friend bool operator ==(const graph_iterator& lhs, + const graph_iterator& rhs); + template + friend bool operator !=(const graph_iterator& lhs, + const graph_iterator& rhs); }; }//end of namespace Detail + //ΣΠΟςΝΌ template> class directed_graph :public Detail::graph < Index, Value, EqualFunc > { public: