#include #include #include #include template struct Node; template using Node_ptr = std::unique_ptr>; template struct Node{ T value; Node_ptr small; Node_ptr big; void dump(std::ofstream& ofs) const; }; template class Tree{ Node_ptr root; Node_ptr* find(T val); Node_ptr* find_to_swap(Node_ptr* unwanted); 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 Node_ptr* Tree::find_to_swap(Node_ptr* unwanted){ if((*unwanted)->small) unwanted = &(*unwanted)->small; else return nullptr; while((*unwanted)->big) unwanted = &(*unwanted)->big; return unwanted; } template bool Tree::del(T val){ Node_ptr* unwanted = find(val); if(!unwanted) return false; Node_ptr* to_swap = find_to_swap(unwanted); if(!to_swap){ (*unwanted).reset((*unwanted)->big.release()); } else{ std::swap((*unwanted)->value, (*to_swap)->value); (*to_swap).reset((*to_swap)->small.release()); } return true; } template bool Tree::insert(T val){ std::unique_ptr> node = std::make_unique>(); node->value = val; if (!root){ root.swap(node); return true; } else{ Node* temp = root.get(); while(temp){ if(val < temp->value){ if(temp->small) temp = temp->small.get(); else{ temp->small.swap(node); return true; } } else if(val > temp->value){ if(temp->big) temp = temp->big.get(); else{ temp->big.swap(node); return true; } } else return false; } return false; } } template void Node::dump(std::ofstream& ofs) const { if (small) { ofs << value << " -> " << small->value << '\n'; small->dump(ofs); } if (big) { ofs << value << " -> " << big->value << '\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 = {3, 6, 8, -1, 7, 0, 9, 2, -11, 5}; 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(); } }