diff --git a/TinySTL/Detail/Graph.impl.h b/TinySTL/Detail/Graph.impl.h index f5e867e..db65679 100644 --- a/TinySTL/Detail/Graph.impl.h +++ b/TinySTL/Detail/Graph.impl.h @@ -3,25 +3,25 @@ namespace TinySTL{ namespace Detail{ template - typename graph::node& + typename graph::node_type& graph::new_node(const Index& index, const Value& val){ auto ptr = nodeAllocator::allocate(); - nodeAllocator::construct(ptr, node(index, val)); + nodeAllocator::construct(ptr, node_type(index, val)); return *ptr; } template - void graph::del_node(node *p){ + void graph::del_node(node_type *p){ nodeAllocator::destroy(p); nodeAllocator::deallocate(p); } template - typename graph::node& + typename graph::node_type& graph::get_node(const Index& index){ for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) return pair.first; } - return node(); + return node_type(); } template void graph::cleanup(){ @@ -40,9 +40,9 @@ namespace TinySTL{ return false; } template - typename graph::node_sets + typename graph::nodes_set_type graph::empty_node_set(){ - return node_sets(); + return nodes_set_type(); } template bool graph::empty()const{ @@ -80,22 +80,22 @@ namespace TinySTL{ return size_; } template - typename graph::node_sets + typename graph::nodes_set_type graph::adjacent_nodes(const Index& index){ - node_sets s; + nodes_set_type s; for (auto it = begin(index); it != end(index); ++it){ s.push_back(*it); } return s; } template - typename graph::node_sets - graph::adjacent_nodes(const node& n){ + typename graph::nodes_set_type + graph::adjacent_nodes(const node_type& n){ return adjacent_nodes(n.first); } template void graph::DFS(const Index& index, visiter_func_type func){ - node *start = &(get_node(index)); + node_type *start = &(get_node(index)); Unordered_set, EqualFunc> visited(7); auto nodes = adjacent_nodes(start->first); @@ -108,14 +108,14 @@ namespace TinySTL{ } template void graph::BFS(const Index& index, visiter_func_type func){ - node *start = &(get_node(index)); + node_type *start = &(get_node(index)); Unordered_set, EqualFunc> visited(7); auto nodes = adjacent_nodes(start->first); func(*start); visited.insert(start->first); do{ - node_sets temp; + nodes_set_type temp; for (auto it = nodes.begin(); it != nodes.end(); ++it){ if (visited.count(it->first) == 0){//has not visited func(*it); @@ -136,14 +136,19 @@ namespace TinySTL{ oss << "[" << oit->first << "," << oit->second << "]" << ":"; auto eit = end(oit->first); for (auto iit = begin(oit->first); iit != eit; ++iit){ - oss << "[" << iit->first << ", " << iit->second << "]" << "-"; + oss << "[" << iit->first << ", " << iit->second << "]" << "->"; } - oss << "[nil,nil]" << std::endl << std::setw(4) << "|" << std::endl; + oss << "[nil]" << std::endl << std::setw(4) << "|" << std::endl; } - oss << "[nil,nil]" << std::endl; + oss << "[nil]" << std::endl; str.append(oss.str().c_str()); return str; } + template + typename graph::equal_func_type + graph::get_equal_func()const{ + return equal_func; + } //******************************************************************************** template inner_iterator& inner_iterator::operator ++(){ @@ -193,11 +198,11 @@ namespace TinySTL{ template directed_graph::directed_graph():graph(){} template - void directed_graph::add_node_helper(const Index& index, const node_sets& nodes){ + void directed_graph::add_node_helper(const Index& index, const nodes_set_type& nodes){ if (nodes.empty()) return; //find node n's list - list* l; + list* l; for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) l = &(pair.second); @@ -210,36 +215,42 @@ namespace TinySTL{ } } template - void directed_graph::add_node(const node& n, const node_sets& nodes){ + void directed_graph::add_node(const node_type& n, const nodes_set_type& nodes){ if (!is_contained(n.first)){ - nodes_.push_front(make_pair(n, list())); + nodes_.push_front(make_pair(n, list())); ++size_; } add_node_helper(n.first, nodes); } template - void directed_graph::add_node(const Index& index, const node_sets& nodes){ + void directed_graph::add_node(const Index& index, const nodes_set_type& nodes){ add_node_helper(index, nodes); } template void directed_graph::delete_node(const Index& index){ for (auto oit = nodes_.begin(); oit != nodes_.end();){ - if (equal_func((oit->first).first, index)) + auto& l = oit->second; + if (equal_func((oit->first).first, index)){ + for (auto iit = l.begin(); iit != l.end(); ++iit){ + del_node(&(*iit)); + } + del_node(&(oit->first)); oit = nodes_.erase(oit); - else{ - auto& l = oit->second; + }else{ for (auto iit = l.begin(); iit != l.end();){ - if (equal_func(iit->first, index)) + if (equal_func(iit->first, index)){ + del_node(&(*iit)); iit = l.erase(iit); - else + }else{ ++iit; + } } ++oit; } } } template - void directed_graph::delete_node(const node& item){ + void directed_graph::delete_node(const node_type& item){ delete_node(item.first); } } \ No newline at end of file diff --git a/TinySTL/Graph.h b/TinySTL/Graph.h index 6382fbd..76cb798 100644 --- a/TinySTL/Graph.h +++ b/TinySTL/Graph.h @@ -2,6 +2,7 @@ #define _GRAPH_H_ #include "Allocator.h" +#include "Iterator.h" #include "List.h" #include "String.h" #include "Unordered_set.h" @@ -28,35 +29,35 @@ namespace TinySTL{ typedef Index index_type; typedef Value value_type; typedef EqualFunc equal_func_type; - typedef pair node; - typedef vector node_sets; - typedef inner_iterator inner_iterator; + typedef pair node_type; + typedef vector nodes_set_type; + typedef allocator nodeAllocator; + typedef std::function visiter_func_type; typedef outter_iterator iterator; - typedef allocator nodeAllocator; - typedef std::function visiter_func_type; + typedef inner_iterator inner_iterator; public: graph() :size_(0){}; virtual ~graph(){ cleanup(); }; //node can be not in the graph - virtual void add_node(const node& item, const node_sets& nodes) = 0; + virtual void add_node(const node_type& item, const nodes_set_type& nodes) = 0; //node of the index must in the graph - virtual void add_node(const Index& index, const node_sets& nodes) = 0; + virtual void add_node(const Index& index, const nodes_set_type& nodes) = 0; - virtual void delete_node(const node& item) = 0; + virtual void delete_node(const node_type& item) = 0; virtual void delete_node(const Index& index) = 0; void DFS(const Index& index, visiter_func_type func); void BFS(const Index& index, visiter_func_type func); - node& new_node(const Index& index, const Value& val); - void del_node(node *p); - node& get_node(const Index& index); + node_type& new_node(const Index& index, const Value& val); + void del_node(node_type *p); + node_type& get_node(const Index& index); bool is_contained(const Index& index); - inline static node_sets empty_node_set(); - node_sets adjacent_nodes(const Index& index); - node_sets adjacent_nodes(const node& n); + inline static nodes_set_type empty_node_set(); + nodes_set_type adjacent_nodes(const Index& index); + nodes_set_type adjacent_nodes(const node_type& n); inline bool empty()const; inline size_t size()const; @@ -65,9 +66,10 @@ namespace TinySTL{ inline iterator begin(); inline iterator end(); + equal_func_type get_equal_func()const; string to_string(); protected: - list>> nodes_; + list>> nodes_; equal_func_type equal_func; size_t size_; protected: @@ -75,19 +77,22 @@ namespace TinySTL{ }; template> - class inner_iterator{ + class inner_iterator :public iterator::node_type>{ public: friend class graph < Index, Value, EqualFunc > ; typedef graph* cntrPtr; typedef graph graph_type; - typedef typename list::iterator inner_it_type; + typedef typename list::iterator inner_it_type; public: explicit inner_iterator(cntrPtr c = nullptr, inner_it_type iit = inner_it_type()) :container_(c), inner_it_(iit){} + inner_iterator& operator ++(); const inner_iterator operator ++(int); - typename graph_type::node& operator*(){ return *inner_it_; } - typename graph_type::node* operator ->(){ return &(operator*()); } + + typename graph_type::node_type& operator*(){ return *inner_it_; } + typename graph_type::node_type* operator ->(){ return &(operator*()); } private: cntrPtr container_; inner_it_type inner_it_; @@ -100,22 +105,25 @@ namespace TinySTL{ const inner_iterator& rhs); }; template> - class outter_iterator{ + class outter_iterator :public iterator::node_type>{ public: friend class graph < Index, Value, EqualFunc >; typedef graph* cntrPtr; typedef graph graph_type; - typedef typename list>>::iterator outter_it_type; + typedef typename list>>::iterator outter_it_type; private: cntrPtr container_; outter_it_type outter_it_; public: explicit outter_iterator(cntrPtr c = nullptr, outter_it_type oit = outter_it_type()) :container_(c), outter_it_(oit){} + outter_iterator& operator ++(); const outter_iterator operator ++(int); - typename graph_type::node& operator*(){ return outter_it_->first; } - typename graph_type::node* operator ->(){ return &(operator*()); } + + typename graph_type::node_type& operator*(){ return outter_it_->first; } + typename graph_type::node_type* operator ->(){ return &(operator*()); } public: template friend bool operator ==(const outter_iterator& lhs, @@ -126,20 +134,20 @@ namespace TinySTL{ }; }//end of namespace Detail - //ΣΠΟςΝΌ + //directed graph template> class directed_graph :public Detail::graph < Index, Value, EqualFunc > { public: directed_graph(); ~directed_graph(){} - //node n -> every node in the nodes set - void add_node(const node& n, const node_sets& nodes) override final; - void add_node(const Index& index, const node_sets& nodes) override final; + //node n -> every node_type in the nodes set + void add_node(const node_type& n, const nodes_set_type& nodes) override final; + void add_node(const Index& index, const nodes_set_type& nodes) override final; - void delete_node(const node& item) override final; + void delete_node(const node_type& item) override final; void delete_node(const Index& index) override final; private: - void add_node_helper(const Index& index, const node_sets& nodes); + void add_node_helper(const Index& index, const nodes_set_type& nodes); }; }