From 32800c462115a4fe75bb8c861c89c51bcdaa8a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=93=E8=88=AA?= <1210603696@qq.com> Date: Fri, 31 Oct 2014 14:42:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TinySTL/AVLTree.h | 53 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/TinySTL/AVLTree.h b/TinySTL/AVLTree.h index 7b05f97..f3ce4de 100644 --- a/TinySTL/AVLTree.h +++ b/TinySTL/AVLTree.h @@ -42,9 +42,9 @@ namespace TinySTL{ avl_tree& operator = (const avl_tree&) = delete; ~avl_tree(){ destroyAndDeallocateAllNodes(root_); } - void insert(const T& val);//todo + void insert(const T& val); template - void insert(Iterator first, Iterator last);//todo + void insert(Iterator first, Iterator last); void erase(const T& val);//todo size_t height()const{ return getHeight(root_); } @@ -90,6 +90,7 @@ namespace TinySTL{ } private: void insert_elem(const T& val, node *&p); + void erase_elem(const T& val, node *&p); void destroyAndDeallocateAllNodes(node *p){ if (p != 0){ destroyAndDeallocateAllNodes(p->left_); @@ -107,6 +108,51 @@ namespace TinySTL{ void print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const; };// end of avl_tree template + void avl_tree::erase_elem(const T& val, node *&p){ + if (p == 0) + return; + if (p->data_ < val){ + erase_elem(val, p->right_); + }else if (p->data_ > val){ + erase_elem(val, p->left_); + }else{// found + if (p->left_ != 0 && p->right_ != 0){//has two children + size_t choose = size_ % 2; + //随机选择删除左右,使得删除操作更平衡 + auto pos = (choose == 0 ? + const_cast(find_min_aux(p->right_).ptr_) : const_cast(find_max_aux(p->left_).ptr_)); + p->data_ = pos->data_; + (choose == 0 ? erase_elem(pos->data_, p->right_) : erase_elem(pos->data_, p->left_)); + }else{ //has one or no child + auto temp = p; + if (p->left_ == 0) + p = p->right_; + else + p = p->left_; + dataAllocator::deallocate(temp); + --size_; + } + } + if (p != 0){//最后更新p的节点高度信息和旋转维持平衡 + p->height_ = max(getHeight(p->left_), getHeight(p->right_)) + 1; + if (getHeight(p->left_) - getHeight(p->right_) == 2){ + if (p->left_->right_ == 0) + singleLeftLeftRotate(p); + else + doubleLeftRightRotate(p); + }else if (getHeight(p->right_) - getHeight(p->left_) == 2){ + if (p->right_->left_ == 0) + singleRightRightRotate(p); + else + doubleRightLeftRotate(p); + } + } + } + template + void avl_tree::erase(const T& val){ + return erase_elem(val, root_); + } + template void avl_tree::insert_elem(const T& val, node *&p){ if (p == 0){ p = dataAllocator::allocate(); @@ -131,8 +177,7 @@ namespace TinySTL{ p = doubleLeftRightRotate(p); } } - int l = getHeight(p->left_), r = getHeight(p->right_); - p->height_ = max(l, r) + 1; + p->height_ = max(getHeight(p->left_), getHeight(p->right_)) + 1; } template void avl_tree::insert(const T& val){