diff --git a/TinySTL/AVLTree.h b/TinySTL/AVLTree.h index 3912e6e..fa13409 100644 --- a/TinySTL/AVLTree.h +++ b/TinySTL/AVLTree.h @@ -2,13 +2,17 @@ #define _AVL_TREE_H_ #include "Allocator.h" +#include "Stack.h" + +#include namespace TinySTL{ //class of avl tree template class avl_tree{ - public: - typename T value_type; + private: + template + friend class avl_iter; private: struct node{ T data_; @@ -18,13 +22,23 @@ namespace TinySTL{ :data_(d), left_(l), right_(r), height_(h){} }; typedef TinySTL::allocator dataAllocator; + public: + typedef T value_type; + typedef avl_iter const_iterator; + typedef const T& const_reference; private: node *root_; + size_t size_; public: - avl_tree() :root_(0){} + avl_tree() :root_(0), size_(0){} avl_tree(const avl_tree&) = delete; avl_tree& operator = (const avl_tree&) = delete; ~avl_tree(){ destroyAndDeallocateAllNodes(root_); } + + size_t height()const{ return root_ == 0 ? -1 : root_->height_; } + size_t size()const{ return size_; } + bool empty()const{ return root_ == 0; } + /*const_iterator root(){ return const_iterator(root_, this); }*/ private: void destroyAndDeallocateAllNodes(node *p){ if (p != 0){ @@ -35,6 +49,116 @@ namespace TinySTL{ } } }; + + namespace{ + //class of bst iterator + template//T = node + class avl_iter{ + private: + template + friend class avl_tree; + private: + typedef typename avl_tree::vaule_type value_type; + typedef typename avl_tree::const_reference const_reference; + typedef typename const T::value_type *const_pointer; + typedef avl_tree * cntrPtr; + private: + const T *ptr_; + cntrPtr container_; + stack parent_;//保存从root到ptr_的父节点的路径 + std::set visited_; + public: + avl_iter(const T *ptr, cntrPtr container) + :ptr_(ptr), container_(container){ + auto temp = container_->root_; + while (temp &&ptr_ && temp != ptr_ && temp->data_ != ptr_->data_){ + parent_.push(temp); + if (temp->data_ < ptr_->data_) + temp = temp->right_; + else if (temp->data_ > ptr_->data_) + temp = temp->left_; + } + } + + operator const T*(){ return ptr_; } + const_reference operator*(){ return ptr_->data_; } + const_pointer operator ->(){ return &(operator*()); } + + avl_iter left()const{ return avl_iter(ptr_->left_, container_); } + avl_iter right()const{ return avl_iter(ptr_->right_, container_); } + + avl_iter& operator ++(); + avl_iter operator ++(int); + avl_iter& operator --(); + avl_iter operator --(int); + public: + template + friend bool operator ==(const avl_iter& it1, const avl_iter& it2); + template + friend bool operator !=(const avl_iter& it1, const avl_iter& it2); + };//end of avl_iter + template + avl_iter& avl_iter::operator ++(){ + visited_.insert(ptr_);//设为已访问 + if (ptr_->right_ != 0){ + parent_.push(ptr_); + ptr_ = ptr_->right_; + while (ptr_ != 0 && ptr_->left_ != 0){ + parent_.push(ptr_); + ptr_ = ptr_->left_; + } + } + else{ + if (!parent_.empty() && visited_.count(parent_.top()) == 0){//父节点未访问 + ptr_ = parent_.top(); + parent_.pop(); + } + else{ + ptr_ = 0; + } + } + return *this; + } + template + avl_iter avl_iter::operator ++(int){ + auto res = *this; + ++*this; + return res; + } + template + avl_iter& avl_iter::operator --(){ + visited_.erase(ptr_);//设为未访问 + if (ptr_->left_ != 0){ + parent_.push(ptr_); + ptr_ = ptr_->left_; + while (ptr_ && ptr_->right_){ + parent_.push(ptr_); + ptr_ = ptr_->right_; + } + } + else{ + if (!parent_.empty() && visited_.count(parent_.top()) == 1){//父节点已经访问了 + ptr_ = parent_.top(); + parent_.pop(); + } + } + return *this; + } + template + avl_iter avl_iter::operator --(int){ + auto res = *this; + --*this; + return res; + } + template + bool operator ==(const avl_iter& it1, const avl_iter& it2){ + return it1.ptr_ == it2.ptr_; + } + template + bool operator !=(const avl_iter& it1, const avl_iter& it2){ + return !(it1 == it2); + } + } } #endif \ No newline at end of file