24template<
typename ReturnType,
typename... Types>
26 std::enable_if_t<tpf::types::is_same_v<tpf::remove_cv_ref_t<Types>...>, ReturnType>;
28template<
typename ElementType>
34 ascending_order = in_order, post_order, descending_order };
36 enum class child_status:
int { left_child = -1, no_child = 0, right_child = 1};
41 mutable int m_height{1};
50 int height(
bool bRecalculate =
false)
const
54 int left_height = 1, right_height = 1;
57 left_height += this->m_left->height(
false);
60 right_height += this->m_right->height(
false);
63 this->m_height = left_height > right_height ?
64 left_height : right_height;
67 return this->m_height;
73 auto parent_ptr = this->m_parent;
77 auto old_height = parent_ptr->m_height;
79 if(old_height != parent_ptr->height(
true))
81 parent_ptr = parent_ptr->m_parent;
85 parent_ptr->height(
true);
87 parent_ptr = parent_ptr->m_parent;
95 if(this->m_left && this->m_left.get() == child)
98 else if(this->m_right && this->m_right.get() == child)
107 os <<
"node_" << this->m_value;
115 <<
" [ shape=oval, label = \"V:"
117 <<
" H:"<< this->m_height <<
"\"] ;";
134 os <<
" [style = dashed, color = red] ; " <<
nl;
136 os <<
" [style = dashed, color = blue] ; " <<
nl;
143 this->m_left->get_node_name(os) <<
" [ color = red ] ;" <<
nl;
146 this->m_left->print_node(os);
153 this->m_right->get_node_name(os) <<
" [color = blue ] ; " <<
nl;
156 this->m_right->print_node(os);
163 os <<
"digraph G { " <<
nl;
172 const ElementType&
get()
const {
return this->m_value; }
179 if(value == this->m_value)
185 if(this->m_left && (ptr = this->m_left->
find(value)))
188 if(this->m_right && (ptr = this->m_right->
find(value)))
195 m_value{value}, m_parent{parent} { }
199 template<
typename Type>
204 if(value == this->m_value)
206 else if(value < this->m_value)
210 return this->m_left->insert(std::forward<Type>(value));
215 this->m_left.reset(
new binary_node{std::forward<Type>(value),
this} );
218 this->m_left->update_height();
227 return this->m_right->insert(std::forward<Type>(value));
232 this->m_right.reset(
new binary_node{std::forward<Type>(value),
this});
235 this->m_right->update_height();
244 template<
typename Type,
typename... Types>
250 bool result = this->
insert(std::forward<Type>(arg));
252 if constexpr(
sizeof...(args) != 0)
255 return result && this->
insert(std::forward<Types>(args)...);
270 os << this->m_value <<
nl;
273 this->m_left->visit_nodes(os, order);
276 this->m_right->visit_nodes(os, order);
283 this->m_left->visit_nodes(os, order);
286 this->m_right->visit_nodes(os, order);
288 os << this->m_value <<
nl;
296 this->m_right->visit_nodes(os, order);
298 os << this->m_value <<
nl;
301 this->m_left->visit_nodes(os, order);
310 this->m_left->visit_nodes(os, order);
312 os << this->m_value <<
nl;
315 this->m_right->visit_nodes(os, order);
347 root.visit_nodes(os, visit_mode::ascending_order);
353 root.visit_nodes(os, visit_mode::descending_order);
368 root.
insert(8, 15, 7, 9, 12, 17, 6, 16, 18, 25);
370 if(
auto ptr = root.find(6))
372 stream <<
"Value found: " << ptr->get() <<
endl;
379 if(
auto ptr = root.find(20) )
381 stream <<
"Value found: " << ptr->get() <<
endl;
400 root.
insert(8, 15, 7, 9, 12, 17, 6, 16, 18);
407int main(
int argc,
const char* argv[])
422 stream <<
"Usage: " << argv[0] <<
" node list " <<
endl;
423 stream <<
"Example: "<<argv[0] <<
" 10 8 15 7 9 12 17 6 16 18 > binary_tree.gv" <<
endl;
424 stream <<
"dot -Tpng binary_tree.gv -o binary_tree.png" <<
endl;
431 for(
int i = 2; i < argc; ++i)
433 root.
insert( std::atoi(argv[i]) );
void test_ascending_descending_order()
void test_find_binary_tree()
int main(int argc, const char *argv[])
std::enable_if_t< tpf::types::is_same_v< tpf::remove_cv_ref_t< Types >... >, ReturnType > enable_if_all_types_are_the_same_t
void test_build_digraph()
typename binary_node< ElementType >::node_ptr_t node_ptr_t
typename graph_t::visit_mode visit_mode
binary_node * find(ElementType value)
enable_if_all_types_are_the_same_t< bool, ElementType, Type, Types... > insert(Type &&arg, Types &&... args)
child_status get_child_status(binary_node *child)
tpf::sstream & get_node_name(tpf::sstream &os)
const ElementType & get() const
void print_node(tpf::sstream &os)
std::unique_ptr< binary_node > node_ptr_t
tpf::sstream & get_node_definition(tpf::sstream &os)
bool insert(ElementType value)
enable_if_all_types_are_the_same_t< bool, ElementType, Type > insert(Type &&value)
binary_node(ElementType value=ElementType{}, binary_node *parent=nullptr)
int height(bool bRecalculate=false) const
void visit_nodes(tpf::sstream &os, visit_mode order=visit_mode::in_order)
Stream output operators << are implemented.