#include #include #include #include template struct Node; template using Node_ptr = std::unique_ptr>; template struct Node{ T value; int max_depth; Node_ptr small; Node_ptr big; bool add(T val); bool add_to_child(Node_ptr* child, T val); void update_depth(); void dump(std::ofstream& ofs) const; Node(T v): value{v}, max_depth{0}, small{nullptr}, big{nullptr}{} }; template class Tree{ Node_ptr root; Node_ptr* find(T val); bool try_to_del(Node_ptr* node, T val); public: bool insert(T val); bool del(T val); void print() const; }; template Node_ptr* Tree::find(T val){ for(Node_ptr* n = &root; *n;){ if(val == (*n)->value) return n; else if(val < (*n)->value) n = &(*n)->small; else n = &(*n)->big; } return nullptr; } template bool Tree::insert(T val){ if(!root){ root = std::make_unique>(val); return true; } else return root->add(val); } template bool Node::add(T val){ if (val == value) return false; else if (val < value) return add_to_child(&small, val); else return add_to_child(&big, val); } template bool Node::add_to_child(Node_ptr* child, T val){ if(!(*child)){ *child = std::make_unique>(val); update_depth(); return true; } else{ if((*child)->add(val)){ update_depth(); return true; } return false; } } template bool Tree::del(T val){ if(!root) return false; else return try_to_del(&root, val); } template bool Tree::try_to_del(Node_ptr* node, T val){ if(val == (*node)->value) { Node_ptr* temp = node; std::vector*> path; if((*node)->small) { path.push_back(temp); std::cout << "pushing " << (*temp)->value << "\n"; temp = &(*node)->small; } else { node->reset((*node)->big.release()); return true; } while((*temp)->big){ path.push_back(temp); std::cout << "pushing " << (*temp)->value << "\n"; temp = &(*temp)->big; } //mam temp na 'to swap' nodu... std::swap((*node)->value, (*temp)->value); temp->reset((*temp)->small.release()); for(int i = path.size() -1; i >= 0; i--) (*path[i])->update_depth(); path.clear(); return true; } else if(val < (*node)->value){ if( ! (*node)->small) return false; else { if(try_to_del(&(*node)->small, val)){ (*node)->update_depth(); return true; } return false; } } else { if( ! (*node)->big) return false; else { if(try_to_del(&(*node)->big, val)){ (*node)->update_depth(); return true; } return false; } } } template void Node::update_depth(){ if(small && big) max_depth = std::max(small->max_depth, big->max_depth) + 1; else if (small) max_depth = small->max_depth + 1; else if (big) max_depth = big->max_depth + 1; else max_depth = 0; } template void Node::dump(std::ofstream& ofs) const { if (small) { ofs << '"' << value << " : " << max_depth << '"' << " -> " << '"' << small->value << " : " << small->max_depth << '"' << '\n'; small->dump(ofs); } if (big) { ofs << '"' << value << " : " << max_depth << '"' << " -> " << '"' << big->value << " : " << big->max_depth << '"' << '\n'; big->dump(ofs); } } template void Tree::print() const { std::ofstream ofs; ofs.open("viz.dot"); ofs << "digraph Tree {\n"; if(root) root->dump(ofs); ofs << "}"; ofs.close(); system("cat viz.dot | dot -Tx11"); } int main(){ Tree t; std::vector v = {9, 2, 5, 7, 4, 8, -1, 15, 12, 17, 10, 13}; for(auto i : v){ if(t.insert(i)) std::cout << "added " << i << "\n"; else std::cout << "failed at adding " << i << "\n"; t.print(); } for(auto i : v){ if(t.del(i)) std::cout << "deleted " << i << "\n"; else std::cout << "failed at deleting " << i << "\n"; t.print(); } }