Graph.impl.h 9.2 KB
Newer Older
邹晓航 已提交
1 2 3 4 5
#include "../Graph.h"

namespace TinySTL{
	namespace Detail{
		template<class Index, class Value, class EqualFunc>
重构  
邹晓航 已提交
6 7 8
		typename graph<Index, Value, EqualFunc>::node_type
			graph<Index, Value, EqualFunc>::make_node(const Index& index, const Value& val){
			return node_type(index, val);
邹晓航 已提交
9 10
		}
		template<class Index, class Value, class EqualFunc>
bug fix  
邹晓航 已提交
11
		typename const graph<Index, Value, EqualFunc>::node_type& 
邹晓航 已提交
12 13 14 15 16
			graph<Index, Value, EqualFunc>::get_node(const Index& index){
			for (auto& pair : nodes_){
				if (equal_func(pair.first.first, index))
					return pair.first;
			}
bug fix  
邹晓航 已提交
17 18
			static node_type empty_node;
			return empty_node;
邹晓航 已提交
19 20
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
21
		bool graph<Index, Value, EqualFunc>::is_contained(const Index& index){
邹晓航 已提交
22
			for (auto& pair : nodes_){
邹晓航 已提交
23
				if (equal_func(pair.first.first, index))
邹晓航 已提交
24 25 26 27 28
					return true;
			}
			return false;
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
29
		typename graph<Index, Value, EqualFunc>::nodes_set_type
邹晓航 已提交
30
			graph<Index, Value, EqualFunc>::empty_node_set(){
邹晓航 已提交
31
			return nodes_set_type();
邹晓航 已提交
32
		}
邹晓航 已提交
33 34 35 36 37
		template<class Index, class Value, class EqualFunc>
		bool graph<Index, Value, EqualFunc>::empty()const{
			return nodes_.empty();
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
38
		typename graph<Index, Value, EqualFunc>::inner_iterator
邹晓航 已提交
39 40 41
			graph<Index, Value, EqualFunc>::begin(const Index& index){
			for (auto& pair : nodes_){
				if (equal_func(pair.first.first, index))
邹晓航 已提交
42
					return inner_iterator(this, (pair.second).begin());
邹晓航 已提交
43 44 45 46
			}
			return end(index);
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
47
		typename graph<Index, Value, EqualFunc>::inner_iterator
邹晓航 已提交
48 49 50
			graph<Index, Value, EqualFunc>::end(const Index& index){
			for (auto& pair : nodes_){
				if (equal_func(pair.first.first, index))
邹晓航 已提交
51
					return inner_iterator(this, (pair.second).end());
邹晓航 已提交
52
			}
邹晓航 已提交
53 54 55 56 57 58 59 60 61
			return inner_iterator();
		}
		template<class Index, class Value, class EqualFunc>
		typename graph<Index, Value, EqualFunc>::iterator graph<Index, Value, EqualFunc>::begin(){
			return iterator(this, nodes_.begin());
		}
		template<class Index, class Value, class EqualFunc>
		typename graph<Index, Value, EqualFunc>::iterator graph<Index, Value, EqualFunc>::end(){
			return iterator(this, nodes_.end());
邹晓航 已提交
62 63 64 65 66
		}
		template<class Index, class Value, class EqualFunc>
		size_t graph<Index, Value, EqualFunc>::size()const{
			return size_;
		}
邹晓航 已提交
67
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
68
		typename graph<Index, Value, EqualFunc>::nodes_set_type 
邹晓航 已提交
69
			graph<Index, Value, EqualFunc>::adjacent_nodes(const Index& index){
邹晓航 已提交
70
			nodes_set_type s;
邹晓航 已提交
71 72 73 74 75 76
			for (auto it = begin(index); it != end(index); ++it){
				s.push_back(*it);
			}
			return s;
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
77 78
		typename graph<Index, Value, EqualFunc>::nodes_set_type
			graph<Index, Value, EqualFunc>::adjacent_nodes(const node_type& n){
邹晓航 已提交
79 80
			return adjacent_nodes(n.first);
		}
邹晓航 已提交
81
		template<class Index, class Value, class EqualFunc>
bug fix  
邹晓航 已提交
82 83 84 85 86 87
		void graph<Index, Value, EqualFunc>::_DFS(node_type& node, 
			visiter_func_type func, Unordered_set<Index, std::hash<Index>, EqualFunc>& visited){
			auto nodes = adjacent_nodes(node.first);
			func(node);
			visited.insert(node.first);
			for (auto& n : nodes){
邹晓航 已提交
88
				if (visited.count(n.first) == 0)//has not visited
bug fix  
邹晓航 已提交
89
					_DFS(n, func, visited);
邹晓航 已提交
90 91
			}
		}
92
		template<class Index, class Value, class EqualFunc>
bug fix  
邹晓航 已提交
93 94
		void graph<Index, Value, EqualFunc>::DFS(const Index& index, visiter_func_type func){
			node_type start = (get_node(index));
邹晓航 已提交
95
			Unordered_set<Index, std::hash<Index>, EqualFunc> visited(7);
bug fix  
邹晓航 已提交
96 97 98 99 100 101 102 103
			_DFS(start, func, visited);
		}
		template<class Index, class Value, class EqualFunc>
		void graph<Index, Value, EqualFunc>::_BFS(node_type& node,
			visiter_func_type func, Unordered_set<Index, std::hash<Index>, EqualFunc>& visited){
			auto nodes = adjacent_nodes(node.first);
			func(node);
			visited.insert(node.first);
邹晓航 已提交
104
			do{
邹晓航 已提交
105
				nodes_set_type temp;
邹晓航 已提交
106 107 108 109
				for (auto it = nodes.begin(); it != nodes.end(); ++it){
					if (visited.count(it->first) == 0){//has not visited
						func(*it);
						visited.insert(it->first);
bug fix  
邹晓航 已提交
110
						auto s = adjacent_nodes(it->first);
邹晓航 已提交
111 112 113 114 115 116 117
						temp.insert(temp.end(), s.begin(), s.end());
					}
				}
				nodes = temp;
			} while (!nodes.empty());
		}
		template<class Index, class Value, class EqualFunc>
bug fix  
邹晓航 已提交
118 119 120 121 122 123
		void graph<Index, Value, EqualFunc>::BFS(const Index& index, visiter_func_type func){
			node_type start = (get_node(index));
			Unordered_set<Index, std::hash<Index>, EqualFunc> visited(7);
			_BFS(start, func, visited);
		}
		template<class Index, class Value, class EqualFunc>
124 125 126 127 128 129 130 131
		string graph<Index, Value, EqualFunc>::to_string(){
			string str;
			std::ostringstream oss;
			for (auto oit = begin(); oit != end(); ++oit){
				
				oss << "[" << oit->first << "," << oit->second << "]" << ":";
				auto eit = end(oit->first);
				for (auto iit = begin(oit->first); iit != eit; ++iit){
bug fix  
邹晓航 已提交
132
					oss << "[" << iit->first << "," << iit->second << "]" << "->";
133
				}
邹晓航 已提交
134
				oss << "[nil]" << std::endl << std::setw(4) << "|" << std::endl;
135
			}
邹晓航 已提交
136
			oss << "[nil]" << std::endl;
137 138 139
			str.append(oss.str().c_str());
			return str;
		}
邹晓航 已提交
140 141 142 143 144
		template<class Index, class Value, class EqualFunc>
		typename graph<Index, Value, EqualFunc>::equal_func_type
			graph<Index, Value, EqualFunc>::get_equal_func()const{
			return equal_func;
		}
邹晓航 已提交
145 146
		//********************************************************************************
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
147
		inner_iterator<Index, Value, EqualFunc>& inner_iterator<Index, Value, EqualFunc>::operator ++(){
邹晓航 已提交
148 149 150 151
			++inner_it_;
			return *this;
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
		const inner_iterator<Index, Value, EqualFunc> inner_iterator<Index, Value, EqualFunc>::operator ++(int){
			auto temp = *this;
			++*this;
			return temp;
		}
		template<class Index, class Value, class EqualFunc>
		bool operator ==(const inner_iterator<Index, Value, EqualFunc>& lhs,
			const inner_iterator<Index, Value, EqualFunc>& rhs){
			return lhs.container_ == rhs.container_ && lhs.inner_it_ == rhs.inner_it_;
		}
		template<class Index, class Value, class EqualFunc>
		bool operator !=(const inner_iterator<Index, Value, EqualFunc>& lhs,
			const inner_iterator<Index, Value, EqualFunc>& rhs){
			return !(lhs == rhs);
		}
		//*********************************************************************************
		template<class Index, class Value, class EqualFunc>
		outter_iterator<Index, Value, EqualFunc>& outter_iterator<Index, Value, EqualFunc>::operator ++(){
			++outter_it_;
			return *this;
		}
		template<class Index, class Value, class EqualFunc>
		const outter_iterator<Index, Value, EqualFunc> outter_iterator<Index, Value, EqualFunc>::operator ++(int){
邹晓航 已提交
175 176 177 178 179
			auto temp = *this;
			++*this;
			return temp;
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
180 181 182
		bool operator ==(const outter_iterator<Index, Value, EqualFunc>& lhs,
			const outter_iterator<Index, Value, EqualFunc>& rhs){
			return lhs.container_ == rhs.container_ && lhs.outter_it_ == rhs.outter_it_;
邹晓航 已提交
183 184
		}
		template<class Index, class Value, class EqualFunc>
邹晓航 已提交
185 186
		bool operator !=(const outter_iterator<Index, Value, EqualFunc>& lhs,
			const outter_iterator<Index, Value, EqualFunc>& rhs){
邹晓航 已提交
187 188
			return !(lhs == rhs);
		}
邹晓航 已提交
189 190 191 192 193
	}//end of Detail

	template<class Index, class Value, class EqualFunc>
	directed_graph<Index, Value, EqualFunc>::directed_graph():graph(){}
	template<class Index, class Value, class EqualFunc>
邹晓航 已提交
194
	void directed_graph<Index, Value, EqualFunc>::add_node_helper(const Index& index, const nodes_set_type& nodes){
邹晓航 已提交
195 196 197
		if (nodes.empty())
			return;
		//find node n's list
邹晓航 已提交
198
		list<typename graph::node_type>* l;
邹晓航 已提交
199
		for (auto& pair : nodes_){
200
			if (equal_func(pair.first.first, index))
邹晓航 已提交
201
				l = &(pair.second);
邹晓航 已提交
202 203
		}
		for (const auto& item : nodes){
邹晓航 已提交
204 205
			l->push_front(item);
			if (!is_contained(item.first)){
邹晓航 已提交
206 207 208 209
				add_node(item, empty_node_set());
			}
		}
	}
210
	template<class Index, class Value, class EqualFunc>
邹晓航 已提交
211
	void directed_graph<Index, Value, EqualFunc>::add_node(const node_type& n, const nodes_set_type& nodes){
212
		if (!is_contained(n.first)){
邹晓航 已提交
213
			nodes_.push_front(make_pair(n, list<typename graph::node_type>()));
214 215 216 217 218
			++size_;
		}
		add_node_helper(n.first, nodes);
	}
	template<class Index, class Value, class EqualFunc>
邹晓航 已提交
219
	void directed_graph<Index, Value, EqualFunc>::add_node(const Index& index, const nodes_set_type& nodes){
220 221
		add_node_helper(index, nodes);
	}
邹晓航 已提交
222 223 224
	template<class Index, class Value, class EqualFunc>
	void directed_graph<Index, Value, EqualFunc>::delete_node(const Index& index){
		for (auto oit = nodes_.begin(); oit != nodes_.end();){
邹晓航 已提交
225 226
			auto& l = oit->second;
			if (equal_func((oit->first).first, index)){
邹晓航 已提交
227
				oit = nodes_.erase(oit);
邹晓航 已提交
228
			}else{
邹晓航 已提交
229
				for (auto iit = l.begin(); iit != l.end();){
重构  
邹晓航 已提交
230
					if (equal_func(iit->first, index))
邹晓航 已提交
231
						iit = l.erase(iit);
重构  
邹晓航 已提交
232
					else
邹晓航 已提交
233 234 235 236 237 238 239
						++iit;
				}
				++oit;
			}
		}
	}
	template<class Index, class Value, class EqualFunc>
邹晓航 已提交
240
	void directed_graph<Index, Value, EqualFunc>::delete_node(const node_type& item){
邹晓航 已提交
241 242
		delete_node(item.first);
	}
bug fix  
邹晓航 已提交
243 244 245 246 247 248 249 250
	template<class Index, class Value, class EqualFunc>
	void directed_graph<Index, Value, EqualFunc>::make_edge(const Index& index1, const Index& index2){
		auto node1 = get_node(index1), node2 = get_node(index2);
		for (auto it = nodes_.begin(); it != nodes_.end(); ++it){
			if (equal_func((it->first).first, index1))
				(it->second).push_front(node2);
		}
	}
邹晓航 已提交
251
}