重构
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace TinySTL{
|
namespace TinySTL{
|
||||||
namespace {
|
namespace Detail{
|
||||||
template<class T>
|
template<class T>
|
||||||
class bst_iter;
|
class bst_iter;
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace TinySTL{
|
|||||||
class binary_search_tree{
|
class binary_search_tree{
|
||||||
private:
|
private:
|
||||||
template<class T>
|
template<class T>
|
||||||
friend class bst_iter;
|
friend class Detail::bst_iter;
|
||||||
private:
|
private:
|
||||||
struct node{
|
struct node{
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
@@ -32,7 +32,7 @@ namespace TinySTL{
|
|||||||
typedef TinySTL::allocator<node> nodeAllocator;
|
typedef TinySTL::allocator<node> nodeAllocator;
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef bst_iter<node> const_iterator;
|
typedef Detail::bst_iter<node> const_iterator;
|
||||||
typedef const T& const_reference;
|
typedef const T& const_reference;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
private:
|
private:
|
||||||
@@ -42,9 +42,7 @@ namespace TinySTL{
|
|||||||
binary_search_tree() :root_(0), size_(0){}
|
binary_search_tree() :root_(0), size_(0){}
|
||||||
binary_search_tree(const binary_search_tree&) = delete;
|
binary_search_tree(const binary_search_tree&) = delete;
|
||||||
binary_search_tree& operator=(const binary_search_tree&) = delete;
|
binary_search_tree& operator=(const binary_search_tree&) = delete;
|
||||||
~binary_search_tree(){
|
~binary_search_tree();
|
||||||
deallocateAllNodes(root_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert(const T& val);
|
void insert(const T& val);
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
@@ -68,14 +66,7 @@ namespace TinySTL{
|
|||||||
void print_postorder(const string& delim = " ", std::ostream& os = std::cout)const;
|
void print_postorder(const string& delim = " ", std::ostream& os = std::cout)const;
|
||||||
void print_levelorder(const string& delim = " ", std::ostream& os = std::cout)const;
|
void print_levelorder(const string& delim = " ", std::ostream& os = std::cout)const;
|
||||||
private:
|
private:
|
||||||
void deallocateAllNodes(node *ptr){
|
void deallocateAllNodes(node *ptr);
|
||||||
if (ptr){
|
|
||||||
deallocateAllNodes(ptr->left_);
|
|
||||||
deallocateAllNodes(ptr->right_);
|
|
||||||
nodeAllocator::destroy(ptr);
|
|
||||||
nodeAllocator::deallocate(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size_t height_aux(node *p)const;
|
size_t height_aux(node *p)const;
|
||||||
void erase_elem(const T& val, node *&ptr);
|
void erase_elem(const T& val, node *&ptr);
|
||||||
void insert_elem(const T& val, node *&ptr);
|
void insert_elem(const T& val, node *&ptr);
|
||||||
@@ -86,193 +77,19 @@ namespace TinySTL{
|
|||||||
void print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
|
void print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
|
||||||
void print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
|
void print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
|
||||||
};//end of bst class
|
};//end of bst class
|
||||||
template<class T>
|
|
||||||
size_t binary_search_tree<T>::height_aux(node *p)const{
|
|
||||||
TinySTL::queue<node *> q/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>node*/, level/*<2A><><EFBFBD>ŵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>node*/;
|
|
||||||
size_t nlevel = 0;
|
|
||||||
if (p != 0){
|
|
||||||
level.push(p);
|
|
||||||
++nlevel;
|
|
||||||
while (!(q.empty() && level.empty())){
|
|
||||||
if (level.empty()){
|
|
||||||
++nlevel;
|
|
||||||
while (!q.empty()){//<2F><>ǰ<EFBFBD><C7B0>Ϊ<EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>nodeȫ<65><C8AB>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>
|
|
||||||
level.push(q.front());
|
|
||||||
q.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto temp = level.front();
|
|
||||||
level.pop();
|
|
||||||
if (temp->left_ != 0) q.push(temp->left_);
|
|
||||||
if (temp->right_ != 0) q.push(temp->right_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nlevel;
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::erase_elem(const T& val, node *&ptr){
|
|
||||||
if (ptr == 0)
|
|
||||||
return;
|
|
||||||
if (ptr->data_ != val){
|
|
||||||
if (val < ptr->data_)
|
|
||||||
return erase_elem(val, ptr->left_);
|
|
||||||
else
|
|
||||||
return erase_elem(val, ptr->right_);
|
|
||||||
}else{ // found
|
|
||||||
if (ptr->left_ != 0 && ptr->right_ != 0){// has two children
|
|
||||||
size_t choose = size_ % 2;
|
|
||||||
//<2F><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD>ң<EFBFBD>ʹ<EFBFBD><CAB9>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
|
|
||||||
auto pos = (choose == 0?
|
|
||||||
const_cast<node *>(find_min_aux(ptr->right_).ptr_) : const_cast<node *>(find_max_aux(ptr->left_).ptr_));
|
|
||||||
ptr->data_ = pos->data_;
|
|
||||||
return (choose == 0 ? erase_elem(pos->data_, ptr->right_) : erase_elem(pos->data_, ptr->left_));
|
|
||||||
}else{ //has one or no child
|
|
||||||
auto temp = ptr;
|
|
||||||
if (ptr->left_ == 0)
|
|
||||||
ptr = ptr->right_;
|
|
||||||
else
|
|
||||||
ptr = ptr->left_;
|
|
||||||
nodeAllocator::destroy(temp);
|
|
||||||
nodeAllocator::deallocate(temp);
|
|
||||||
--size_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::erase(const T& val){
|
|
||||||
erase_elem(val, root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::insert_elem(const T& val, node *&ptr){//<2F>ظ<EFBFBD><D8B8><EFBFBD>Ԫ<EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
if (ptr == 0){
|
|
||||||
ptr = nodeAllocator::allocate();
|
|
||||||
TinySTL::construct(&(ptr->data_), val);
|
|
||||||
//memset(ptr, 0, sizeof(node));
|
|
||||||
//ptr->data_ = val;
|
|
||||||
ptr->left_ = ptr->right_ = 0;
|
|
||||||
++size_;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (val < ptr->data_){
|
|
||||||
return insert_elem(val, ptr->left_);
|
|
||||||
}
|
|
||||||
else if (val > ptr->data_){
|
|
||||||
return insert_elem(val, ptr->right_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::insert(const T& val){
|
|
||||||
insert_elem(val, root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
template<class Iterator>
|
|
||||||
void binary_search_tree<T>::insert(Iterator first, Iterator last){
|
|
||||||
for (; first != last; ++first)
|
|
||||||
insert(*first);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_levelorder(const string& delim, std::ostream& os)const{
|
|
||||||
auto temp = root_;
|
|
||||||
if (temp != 0){
|
|
||||||
std::deque<node *> q;
|
|
||||||
q.push_back(temp);
|
|
||||||
while (!q.empty()){
|
|
||||||
temp = q.front();
|
|
||||||
q.pop_front();
|
|
||||||
if (temp->left_ != 0) q.push_back(temp->left_);
|
|
||||||
if (temp->right_ != 0) q.push_back(temp->right_);
|
|
||||||
os << temp->data_ << delim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_preorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
|
||||||
if (ptr){
|
|
||||||
os << ptr->data_ << delim;
|
|
||||||
print_preorder_aux(delim, os, ptr->left_);
|
|
||||||
print_preorder_aux(delim, os, ptr->right_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_preorder(const string& delim, std::ostream& os)const{
|
|
||||||
print_preorder_aux(delim, os, root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
|
||||||
if (ptr){
|
|
||||||
print_inorder_aux(delim, os, ptr->left_);
|
|
||||||
os << ptr->data_ << delim;
|
|
||||||
print_inorder_aux(delim, os, ptr->right_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_inorder(const string& delim, std::ostream& os)const{
|
|
||||||
print_inorder_aux(delim, os, root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
|
||||||
if (ptr){
|
|
||||||
print_postorder_aux(delim, os, ptr->left_);
|
|
||||||
print_postorder_aux(delim, os, ptr->right_);
|
|
||||||
os << ptr->data_ << delim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
void binary_search_tree<T>::print_postorder(const string& delim, std::ostream& os)const{
|
|
||||||
print_postorder_aux(delim, os, root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_min_aux(const node *ptr)const{
|
|
||||||
while (ptr && ptr->left_ != 0){
|
|
||||||
ptr = ptr->left_;
|
|
||||||
}
|
|
||||||
return const_iterator(ptr, this);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_min()const{
|
|
||||||
return find_min_aux(root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_max_aux(const node *ptr)const{
|
|
||||||
while (ptr && ptr->right_ != 0){
|
|
||||||
ptr = ptr->right_;
|
|
||||||
}
|
|
||||||
return const_iterator(ptr, this);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_max()const{
|
|
||||||
return find_max_aux(root_);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_aux(const T& val, const node *ptr)const{
|
|
||||||
while (ptr){
|
|
||||||
if (val == ptr->data_)
|
|
||||||
break;
|
|
||||||
else if (val < ptr->data_)
|
|
||||||
ptr = ptr->left_;
|
|
||||||
else
|
|
||||||
ptr = ptr->right_;
|
|
||||||
}
|
|
||||||
return const_iterator(ptr, this);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find(const T& val)const{
|
|
||||||
return find_aux(val, root_);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace{
|
namespace Detail{
|
||||||
//class of bst iterator
|
//class of bst iterator
|
||||||
template<class T>//T = node
|
template<class T>//T = node
|
||||||
class bst_iter{
|
class bst_iter{
|
||||||
private:
|
private:
|
||||||
template<class T>
|
template<class T>
|
||||||
friend class binary_search_tree;
|
friend class ::TinySTL::binary_search_tree;
|
||||||
private:
|
private:
|
||||||
typedef typename binary_search_tree<typename T::value_type>::value_type value_type;
|
typedef typename ::TinySTL::binary_search_tree<typename T::value_type>::value_type value_type;
|
||||||
typedef typename binary_search_tree<typename T::value_type>::const_reference const_reference;
|
typedef typename ::TinySTL::binary_search_tree<typename T::value_type>::const_reference const_reference;
|
||||||
typedef typename const T::value_type *const_pointer;
|
typedef typename const T::value_type *const_pointer;
|
||||||
typedef const binary_search_tree<typename T::value_type> * cntrPtr;
|
typedef const ::TinySTL::binary_search_tree<typename T::value_type> * cntrPtr;
|
||||||
private:
|
private:
|
||||||
const T *ptr_;
|
const T *ptr_;
|
||||||
cntrPtr container_;
|
cntrPtr container_;
|
||||||
@@ -280,20 +97,7 @@ namespace TinySTL{
|
|||||||
std::set<const T *> rvisited_;//<2F><>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<C7B7><F1B1BBB7>ʹ<EFBFBD>
|
std::set<const T *> rvisited_;//<2F><>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<C7B7><F1B1BBB7>ʹ<EFBFBD>
|
||||||
std::set<const T *> visited_;//<2F><>ǰ<EFBFBD>ڵ<EFBFBD><DAB5>Ƿ<C7B7><F1B1BBB7>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><D1B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD>
|
std::set<const T *> visited_;//<2F><>ǰ<EFBFBD>ڵ<EFBFBD><DAB5>Ƿ<C7B7><F1B1BBB7>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><D1B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD>
|
||||||
public:
|
public:
|
||||||
bst_iter(const T *ptr, cntrPtr container)
|
bst_iter(const T *ptr, cntrPtr container);
|
||||||
:ptr_(ptr), container_(container){
|
|
||||||
if (!ptr_)
|
|
||||||
return;
|
|
||||||
auto temp = container_->root_;
|
|
||||||
while (temp && 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_; }
|
operator const T*(){ return ptr_; }
|
||||||
const_reference operator*()const{ return ptr_->data_; }
|
const_reference operator*()const{ return ptr_->data_; }
|
||||||
@@ -304,88 +108,14 @@ namespace TinySTL{
|
|||||||
|
|
||||||
bst_iter& operator ++();
|
bst_iter& operator ++();
|
||||||
bst_iter operator ++(int);
|
bst_iter operator ++(int);
|
||||||
//bst_iter& operator --();
|
|
||||||
//bst_iter operator --(int);
|
|
||||||
public:
|
public:
|
||||||
template<class T>
|
template<class T>
|
||||||
friend bool operator ==(const bst_iter<T>& it1, const bst_iter<T>& it2);
|
friend bool operator ==(const bst_iter<T>& it1, const bst_iter<T>& it2);
|
||||||
template<class T>
|
template<class T>
|
||||||
friend bool operator !=(const bst_iter<T>& it1, const bst_iter<T>& it2);
|
friend bool operator !=(const bst_iter<T>& it1, const bst_iter<T>& it2);
|
||||||
};//end of bst_iter
|
};//end of bst_iter
|
||||||
template<class T>
|
|
||||||
bst_iter<T>& bst_iter<T>::operator ++(){
|
|
||||||
visited_.insert(ptr_);//<2F><>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
if (ptr_->right_){//<2F><>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
rvisited_.insert(ptr_);
|
|
||||||
parent_.push(ptr_);
|
|
||||||
ptr_ = ptr_->right_;
|
|
||||||
while (ptr_ && ptr_->left_){
|
|
||||||
parent_.push(ptr_);
|
|
||||||
ptr_ = ptr_->left_;
|
|
||||||
}
|
|
||||||
}else{//node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>ڵ<F2B8B8BD>·<EFBFBD><C2B7><EFBFBD>ƶ<EFBFBD>
|
|
||||||
|
|
||||||
while (!parent_.empty()){
|
|
||||||
ptr_ = parent_.top();
|
|
||||||
parent_.pop();
|
|
||||||
if (visited_.count(ptr_) == 0){//<2F><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
|
|
||||||
visited_.insert(ptr_);
|
|
||||||
break;
|
|
||||||
}else if (rvisited_.count(ptr_) == 0){//<2F><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
rvisited_.insert(ptr_);
|
|
||||||
if (ptr_->right_){
|
|
||||||
parent_.push(ptr_);
|
|
||||||
ptr_ = ptr_->right_;
|
|
||||||
while (ptr_ && ptr_->left_){
|
|
||||||
parent_.push(ptr_);
|
|
||||||
ptr_ = ptr_->left_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr_ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
bst_iter<T> bst_iter<T>::operator ++(int){
|
|
||||||
auto res = *this;
|
|
||||||
++*this;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
//template<class T>
|
|
||||||
//bst_iter<T>& bst_iter<T>::operator --(){
|
|
||||||
// visited_.erase(ptr_);//<2F><>Ϊδ<CEAA><CEB4><EFBFBD><EFBFBD>
|
|
||||||
// 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){//<2F><><EFBFBD>ڵ<EFBFBD><DAB5>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
// ptr_ = parent_.top();
|
|
||||||
// parent_.pop();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return *this;
|
|
||||||
//}
|
|
||||||
//template<class T>
|
|
||||||
//bst_iter<T> bst_iter<T>::operator --(int){
|
|
||||||
// auto res = *this;
|
|
||||||
// --*this;
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
template<class T>
|
|
||||||
bool operator ==(const bst_iter<T>& it1, const bst_iter<T>& it2){
|
|
||||||
return it1.ptr_ == it2.ptr_;
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
bool operator !=(const bst_iter<T>& it1, const bst_iter<T>& it2){
|
|
||||||
return !(it1 == it2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "Detail\BinarySearchTree.impl.h"
|
||||||
#endif
|
#endif
|
||||||
266
TinySTL/Detail/BinarySearchTree.impl.h
Normal file
266
TinySTL/Detail/BinarySearchTree.impl.h
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
#ifndef _BINARY_SEARCH_TREE_IMPL_H_
|
||||||
|
#define _BINARY_SEARCH_TREE_IMPL_H_
|
||||||
|
|
||||||
|
namespace TinySTL{
|
||||||
|
namespace Detail{
|
||||||
|
template<class T>
|
||||||
|
bst_iter<T>::bst_iter(const T *ptr, cntrPtr container)
|
||||||
|
:ptr_(ptr), container_(container){
|
||||||
|
if (!ptr_)
|
||||||
|
return;
|
||||||
|
auto temp = container_->root_;
|
||||||
|
while (temp && 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_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
bst_iter<T>& bst_iter<T>::operator ++(){
|
||||||
|
visited_.insert(ptr_);//<2F><>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (ptr_->right_){//<2F><>node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
rvisited_.insert(ptr_);
|
||||||
|
parent_.push(ptr_);
|
||||||
|
ptr_ = ptr_->right_;
|
||||||
|
while (ptr_ && ptr_->left_){
|
||||||
|
parent_.push(ptr_);
|
||||||
|
ptr_ = ptr_->left_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{//node<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>ڵ<F2B8B8BD>·<EFBFBD><C2B7><EFBFBD>ƶ<EFBFBD>
|
||||||
|
|
||||||
|
while (!parent_.empty()){
|
||||||
|
ptr_ = parent_.top();
|
||||||
|
parent_.pop();
|
||||||
|
if (visited_.count(ptr_) == 0){//<2F><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
|
||||||
|
visited_.insert(ptr_);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (rvisited_.count(ptr_) == 0){//<2F><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
rvisited_.insert(ptr_);
|
||||||
|
if (ptr_->right_){
|
||||||
|
parent_.push(ptr_);
|
||||||
|
ptr_ = ptr_->right_;
|
||||||
|
while (ptr_ && ptr_->left_){
|
||||||
|
parent_.push(ptr_);
|
||||||
|
ptr_ = ptr_->left_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
bst_iter<T> bst_iter<T>::operator ++(int){
|
||||||
|
auto res = *this;
|
||||||
|
++*this;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
bool operator ==(const bst_iter<T>& it1, const bst_iter<T>& it2){
|
||||||
|
return it1.ptr_ == it2.ptr_;
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
bool operator !=(const bst_iter<T>& it1, const bst_iter<T>& it2){
|
||||||
|
return !(it1 == it2);
|
||||||
|
}
|
||||||
|
}//end of Detail namespace
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
binary_search_tree<T>::~binary_search_tree(){
|
||||||
|
deallocateAllNodes(root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::deallocateAllNodes(node *ptr){
|
||||||
|
if (ptr){
|
||||||
|
deallocateAllNodes(ptr->left_);
|
||||||
|
deallocateAllNodes(ptr->right_);
|
||||||
|
nodeAllocator::destroy(ptr);
|
||||||
|
nodeAllocator::deallocate(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
size_t binary_search_tree<T>::height_aux(node *p)const{
|
||||||
|
TinySTL::queue<node *> q/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>node*/, level/*<2A><><EFBFBD>ŵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>node*/;
|
||||||
|
size_t nlevel = 0;
|
||||||
|
if (p != 0){
|
||||||
|
level.push(p);
|
||||||
|
++nlevel;
|
||||||
|
while (!(q.empty() && level.empty())){
|
||||||
|
if (level.empty()){
|
||||||
|
++nlevel;
|
||||||
|
while (!q.empty()){//<2F><>ǰ<EFBFBD><C7B0>Ϊ<EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>nodeȫ<65><C8AB>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>
|
||||||
|
level.push(q.front());
|
||||||
|
q.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto temp = level.front();
|
||||||
|
level.pop();
|
||||||
|
if (temp->left_ != 0) q.push(temp->left_);
|
||||||
|
if (temp->right_ != 0) q.push(temp->right_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nlevel;
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::erase_elem(const T& val, node *&ptr){
|
||||||
|
if (ptr == 0)
|
||||||
|
return;
|
||||||
|
if (ptr->data_ != val){
|
||||||
|
if (val < ptr->data_)
|
||||||
|
return erase_elem(val, ptr->left_);
|
||||||
|
else
|
||||||
|
return erase_elem(val, ptr->right_);
|
||||||
|
}
|
||||||
|
else{ // found
|
||||||
|
if (ptr->left_ != 0 && ptr->right_ != 0){// has two children
|
||||||
|
size_t choose = size_ % 2;
|
||||||
|
//<2F><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD>ң<EFBFBD>ʹ<EFBFBD><CAB9>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
|
||||||
|
auto pos = (choose == 0 ?
|
||||||
|
const_cast<node *>(find_min_aux(ptr->right_).ptr_) : const_cast<node *>(find_max_aux(ptr->left_).ptr_));
|
||||||
|
ptr->data_ = pos->data_;
|
||||||
|
return (choose == 0 ? erase_elem(pos->data_, ptr->right_) : erase_elem(pos->data_, ptr->left_));
|
||||||
|
}
|
||||||
|
else{ //has one or no child
|
||||||
|
auto temp = ptr;
|
||||||
|
if (ptr->left_ == 0)
|
||||||
|
ptr = ptr->right_;
|
||||||
|
else
|
||||||
|
ptr = ptr->left_;
|
||||||
|
nodeAllocator::destroy(temp);
|
||||||
|
nodeAllocator::deallocate(temp);
|
||||||
|
--size_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::erase(const T& val){
|
||||||
|
erase_elem(val, root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::insert_elem(const T& val, node *&ptr){//<2F>ظ<EFBFBD><D8B8><EFBFBD>Ԫ<EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (ptr == 0){
|
||||||
|
ptr = nodeAllocator::allocate();
|
||||||
|
TinySTL::construct(&(ptr->data_), val);
|
||||||
|
//memset(ptr, 0, sizeof(node));
|
||||||
|
//ptr->data_ = val;
|
||||||
|
ptr->left_ = ptr->right_ = 0;
|
||||||
|
++size_;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (val < ptr->data_){
|
||||||
|
return insert_elem(val, ptr->left_);
|
||||||
|
}
|
||||||
|
else if (val > ptr->data_){
|
||||||
|
return insert_elem(val, ptr->right_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::insert(const T& val){
|
||||||
|
insert_elem(val, root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
template<class Iterator>
|
||||||
|
void binary_search_tree<T>::insert(Iterator first, Iterator last){
|
||||||
|
for (; first != last; ++first)
|
||||||
|
insert(*first);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_levelorder(const string& delim, std::ostream& os)const{
|
||||||
|
auto temp = root_;
|
||||||
|
if (temp != 0){
|
||||||
|
std::deque<node *> q;
|
||||||
|
q.push_back(temp);
|
||||||
|
while (!q.empty()){
|
||||||
|
temp = q.front();
|
||||||
|
q.pop_front();
|
||||||
|
if (temp->left_ != 0) q.push_back(temp->left_);
|
||||||
|
if (temp->right_ != 0) q.push_back(temp->right_);
|
||||||
|
os << temp->data_ << delim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_preorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
||||||
|
if (ptr){
|
||||||
|
os << ptr->data_ << delim;
|
||||||
|
print_preorder_aux(delim, os, ptr->left_);
|
||||||
|
print_preorder_aux(delim, os, ptr->right_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_preorder(const string& delim, std::ostream& os)const{
|
||||||
|
print_preorder_aux(delim, os, root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
||||||
|
if (ptr){
|
||||||
|
print_inorder_aux(delim, os, ptr->left_);
|
||||||
|
os << ptr->data_ << delim;
|
||||||
|
print_inorder_aux(delim, os, ptr->right_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_inorder(const string& delim, std::ostream& os)const{
|
||||||
|
print_inorder_aux(delim, os, root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const{
|
||||||
|
if (ptr){
|
||||||
|
print_postorder_aux(delim, os, ptr->left_);
|
||||||
|
print_postorder_aux(delim, os, ptr->right_);
|
||||||
|
os << ptr->data_ << delim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
void binary_search_tree<T>::print_postorder(const string& delim, std::ostream& os)const{
|
||||||
|
print_postorder_aux(delim, os, root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_min_aux(const node *ptr)const{
|
||||||
|
while (ptr && ptr->left_ != 0){
|
||||||
|
ptr = ptr->left_;
|
||||||
|
}
|
||||||
|
return const_iterator(ptr, this);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_min()const{
|
||||||
|
return find_min_aux(root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_max_aux(const node *ptr)const{
|
||||||
|
while (ptr && ptr->right_ != 0){
|
||||||
|
ptr = ptr->right_;
|
||||||
|
}
|
||||||
|
return const_iterator(ptr, this);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_max()const{
|
||||||
|
return find_max_aux(root_);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find_aux(const T& val, const node *ptr)const{
|
||||||
|
while (ptr){
|
||||||
|
if (val == ptr->data_)
|
||||||
|
break;
|
||||||
|
else if (val < ptr->data_)
|
||||||
|
ptr = ptr->left_;
|
||||||
|
else
|
||||||
|
ptr = ptr->right_;
|
||||||
|
}
|
||||||
|
return const_iterator(ptr, this);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename binary_search_tree<T>::const_iterator binary_search_tree<T>::find(const T& val)const{
|
||||||
|
return find_aux(val, root_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user