diff --git a/Tree/AVLTree/avlmhco.hpp b/Tree/AVLTree/avlmhco.hpp new file mode 100644 index 000000000..c4953c0dd --- /dev/null +++ b/Tree/AVLTree/avlmhco.hpp @@ -0,0 +1,665 @@ +//© Copyright 2018 Marcos Oliveira +/*Essa implementação tem como base o algoritmo +do geeksforgeeks para AVLS,no entando programado +com orientação à objeto e com template adicionado*/ +#include +enum class order{preorder,inorder,posorder}; +//© Copyright 2018 Marcos Oliveira +/*Essa implementação tem como base o algoritmo +do geeksforgeeks para AVLS,no entando programado +com orientação à objeto e com template adicionado*/ +#include +enum class order{preorder,inorder,posorder}; + +template +struct node{ + T val; + int rank; + node * right; + node * left; +}; + +template +class avl{ +private: + node * root; + + node * new_node(T value); + + node * insert_real(node * no,T value); + node * remove_real(node * no,T value); + node * remove_min(node * no); + + node * right_rotate(node * no); + node * left_rotate(node * no); + + void preOrder(node * no); + void inOrder(node * no); + void posOrder(node * no); + + bool search_real(node * no, T value); + + bool empty_real(node * no); + + int get_height(node * no); + int get_balance(node * no); +public: + + avl(); + avl(T value); + ~avl(); + + void show(order o); + void insert(T value); + bool search(T value); + void remove(T value); + bool empty(void); +}; + +template +avl::avl(){ + + this->root = nullptr; +} +template +avl::avl(T value){ + + this->root = new_node(value); +} + +template +avl::~avl(){ + while(!this->empty()){ + this->root=remove_real(this->root,this->root->val); + } +} + +template +bool avl::empty_real(node * no){ + if(no == nullptr){ + return true; + }else{ + return false; + } +} + +template +bool avl::empty(void){ + + return empty_real(this->root); +} + +template +void avl::preOrder(node * no){ + if(no == nullptr){ + return; + }else{ + std::cout << no->val <<" "; + preOrder(no->left); + preOrder(no->right); + } +} + +template +void avl::inOrder(node * no){ + if(no == nullptr){ + return; + }else{ + preOrder(no->left); + std::cout << no->val << " "; + preOrder(no->right); + } +} + +template +void avl::posOrder(node * no){ + if(no == nullptr){ + return; + }else{ + preOrder(no->left); + preOrder(no->right); + std::cout << no->val << " "; + } +} + +template +int avl::get_height(node * no){ + if(no == nullptr){ + return 0; + }else{ + return no->rank; + } +} + +template +int avl::get_balance(node * no){ + if(no == nullptr){ + return 0; + }else{ + return (get_height(no->left) - get_height(no->right)); + } +} + +template +node * avl::left_rotate(node *no){ + node * no_dir = no->right; + node * no_sub_es = no_dir->left; + + no_dir->left = no; + no->right = no_sub_es; + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + no_dir->rank = std::max(get_height(no_dir->left),get_height(no_dir->right))+1; + + return no_dir; +} + +template +node * avl::right_rotate(node * no){ + node * no_es = no->left; + node * no_sub_dir = no_es->right; + + no_es->right = no; + no->left = no_sub_dir; + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + no_es->rank = std::max(get_height(no_es->left),get_height(no_es->right))+1; + + return no_es; +} + +template +node * avl::insert_real(node * no,T value){ + if(no == nullptr){ + return new_node(value); + }else if(value < no->val){ + no->left = insert_real(no->left,value); + }else if(value > no->val){ + no->right = insert_real(no->right,value); + }else{ + return no; + } + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + + int bf = get_balance(no); + + if (bf > 1 && value < no->left->val){ + return right_rotate(no); + } + + if (bf < -1 && value > no->right->val){ + return left_rotate(no); + } + + if (bf > 1 && value > no->left->val){ + no->left = left_rotate(no->left); + return right_rotate(no); + } + + if (bf < -1 && value < no->right->val){ + no->right = right_rotate(no->right); + return left_rotate(no); + } + + return no; +} + +template +node * avl::remove_min(node * no){ + node * cur = no; + + while(cur->left != nullptr){ + cur = cur->left; + } + + return cur; +} + +template +node * avl::remove_real(node * no,T value){ + + if(no == nullptr){ + return no; + }else if(value < no->val){ + no->left = remove_real(no->left,value); + }else if(value > no->val){ + no->right = remove_real(no->right,value); + }else{ + if(no->left == nullptr && no->right == nullptr){ + node * temp = no; + no = nullptr; + + delete temp; + }else if(no->left == nullptr){ + node * temp = no->right; + + *no = *temp; + + delete temp; + }else if(no->right == nullptr){ + node * temp = no->left; + + *no = *temp; + + delete temp; + }else{ + node * temp = remove_min(no->right); + + no->val = temp->val; + + no->right = remove_real(no->right,temp->val); + } + } + + + if(no == nullptr){ + return no; + } + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + + int bf = get_balance(no); + + if (bf > 1 && get_balance(no->left) >= 0){ + return right_rotate(no); + } + + if (bf > 1 && get_balance(no->left) < 0){ + no->left = left_rotate(no->left); + return right_rotate(no); + } + + if (bf < -1 && get_balance(no->right) <= 0){ + return left_rotate(no); + } + + if (bf < -1 && get_balance(no->right) > 0){ + no->right = right_rotate(no->right); + return left_rotate(no); + } + + return no; +} + +template +bool avl::search_real(node * no , T value){ + if(no == nullptr){ + return false; + }else if(no->val == value){ + return true; + }else if(no->val < value){ + return search_real(no->right,value); + }else{ + return search_real(no->left,value); + } +} + +template +bool avl::search(T value){ + + return search_real(this->root,value); +} + +template +void avl::insert(T value){ + + this->root = insert_real(this->root,value); +} + +template +node * avl::new_node(T value){ + node * n = new node; + n->val = value; + n->rank = 1; + n->left = nullptr; + n->right = nullptr; + + return n; +} + +template +void avl::show(order o){ + if(o == order::preorder){ + this->preOrder(this->root); + std::cout << std::endl; + }else if(o == order::inorder){ + this->inOrder(this->root); + std::cout << std::endl; + }else if(o == order::posorder){ + this->posOrder(this->root); + std::cout << std::endl; + } +} + +template +void avl::remove(T value){ + + this->root = remove_real(this->root,value); +} +template +struct node{ + T val; + int rank; + node * right; + node * left; +}; + +template +class avl{ +private: + node * root; + + node * new_node(T value); + + node * insert_real(node * no,T value); + node * remove_real(node * no,T value); + node * remove_min(node * no); + + node * right_rotate(node * no); + node * left_rotate(node * no); + + void preOrder(node * no); + void inOrder(node * no); + void posOrder(node * no); + + bool search_real(node * no, T value); + + bool empty_real(node * no); + + int get_height(node * no); + int get_balance(node * no); +public: + + avl(); + avl(T value); + ~avl(); + + void show(order o); + void insert(T value); + bool search(T value); + void remove(T value); + bool empty(void); +}; + +template +avl::avl(){ + + this->root = nullptr; +} +template +avl::avl(T value){ + + this->root = new_node(value); +} + +template +avl::~avl(){ + while(!this->empty()){ + this->root=remove_real(this->root,this->root->val); + } +} + +template +bool avl::empty_real(node * no){ + if(no == nullptr){ + return true; + }else{ + return false; + } +} + +template +bool avl::empty(void){ + + return empty_real(this->root); +} + +template +void avl::preOrder(node * no){ + if(no == nullptr){ + return; + }else{ + std::cout << no->val <<" "; + preOrder(no->left); + preOrder(no->right); + } +} + +template +void avl::inOrder(node * no){ + if(no == nullptr){ + return; + }else{ + preOrder(no->left); + std::cout << no->val << " "; + preOrder(no->right); + } +} + +template +void avl::posOrder(node * no){ + if(no == nullptr){ + return; + }else{ + preOrder(no->left); + preOrder(no->right); + std::cout << no->val << " "; + } +} + +template +int avl::get_height(node * no){ + if(no == nullptr){ + return 0; + }else{ + return no->rank; + } +} + +template +int avl::get_balance(node * no){ + if(no == nullptr){ + return 0; + }else{ + return (get_height(no->left) - get_height(no->right)); + } +} + +template +node * avl::left_rotate(node *no){ + node * no_dir = no->right; + node * no_sub_es = no_dir->left; + + no_dir->left = no; + no->right = no_sub_es; + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + no_dir->rank = std::max(get_height(no_dir->left),get_height(no_dir->right))+1; + + return no_dir; +} + +template +node * avl::right_rotate(node * no){ + node * no_es = no->left; + node * no_sub_dir = no_es->right; + + no_es->right = no; + no->left = no_sub_dir; + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + no_es->rank = std::max(get_height(no_es->left),get_height(no_es->right))+1; + + return no_es; +} + +template +node * avl::insert_real(node * no,T value){ + if(no == nullptr){ + return new_node(value); + }else if(value < no->val){ + no->left = insert_real(no->left,value); + }else if(value > no->val){ + no->right = insert_real(no->right,value); + }else{ + return no; + } + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + + int bf = get_balance(no); + + if (bf > 1 && value < no->left->val){ + return right_rotate(no); + } + + if (bf < -1 && value > no->right->val){ + return left_rotate(no); + } + + if (bf > 1 && value > no->left->val){ + no->left = left_rotate(no->left); + return right_rotate(no); + } + + if (bf < -1 && value < no->right->val){ + no->right = right_rotate(no->right); + return left_rotate(no); + } + + return no; +} + +template +node * avl::remove_min(node * no){ + node * cur = no; + + while(cur->left != nullptr){ + cur = cur->left; + } + + return cur; +} + +template +node * avl::remove_real(node * no,T value){ + + if(no == nullptr){ + return no; + }else if(value < no->val){ + no->left = remove_real(no->left,value); + }else if(value > no->val){ + no->right = remove_real(no->right,value); + }else{ + if(no->left == nullptr && no->right == nullptr){ + node * temp = no; + no = nullptr; + + delete temp; + }else if(no->left == nullptr){ + node * temp = no->right; + + *no = *temp; + + delete temp; + }else if(no->right == nullptr){ + node * temp = no->left; + + *no = *temp; + + delete temp; + }else{ + node * temp = remove_min(no->right); + + no->val = temp->val; + + no->right = remove_real(no->right,temp->val); + } + } + + + if(no == nullptr){ + return no; + } + + no->rank = std::max(get_height(no->left),get_height(no->right))+1; + + int bf = get_balance(no); + + if (bf > 1 && get_balance(no->left) >= 0){ + return right_rotate(no); + } + + if (bf > 1 && get_balance(no->left) < 0){ + no->left = left_rotate(no->left); + return right_rotate(no); + } + + if (bf < -1 && get_balance(no->right) <= 0){ + return left_rotate(no); + } + + if (bf < -1 && get_balance(no->right) > 0){ + no->right = right_rotate(no->right); + return left_rotate(no); + } + + return no; +} + +template +bool avl::search_real(node * no , T value){ + if(no == nullptr){ + return false; + }else if(no->val == value){ + return true; + }else if(no->val < value){ + return search_real(no->right,value); + }else{ + return search_real(no->left,value); + } +} + +template +bool avl::search(T value){ + + return search_real(this->root,value); +} + +template +void avl::insert(T value){ + + this->root = insert_real(this->root,value); +} + +template +node * avl::new_node(T value){ + node * n = new node; + n->val = value; + n->rank = 1; + n->left = nullptr; + n->right = nullptr; + + return n; +} + +template +void avl::show(order o){ + if(o == order::preorder){ + this->preOrder(this->root); + std::cout << std::endl; + }else if(o == order::inorder){ + this->inOrder(this->root); + std::cout << std::endl; + }else if(o == order::posorder){ + this->posOrder(this->root); + std::cout << std::endl; + } +} + +template +void avl::remove(T value){ + + this->root = remove_real(this->root,value); +}