• 谈一谈二叉搜索树中序迭代器的关键设计


    之前在完成TinySTL项目中二叉搜索树的设计时发现要想完成其中序迭代器的设计,关键的一步是完成迭代器的++操作,当实现了这个操作时那么这个迭代器的90%的操作都可以很快的完成了。

    下面先来看看node的定义:

            struct node{
                typedef T value_type;
                T data_;
                node *left_;
                node *right_;
                explicit node(T d = T(), node *l = 0, node *r = 0)
                    :data_(d), left_(l), right_(r){}
            };

    在二叉树中有:

    下面来看看我是怎样实现++操作的。

    首先是初始化迭代器:

     1         template<class T>
     2         bst_iter<T>::bst_iter(const T *ptr, cntrPtr container)
     3             :ptr_(ptr), container_(container){
     4             if (!ptr_)
     5                 return;
     6             auto temp = container_->root_;
     7             while (temp && temp != ptr_ && temp->data_ != ptr_->data_){
     8                 parent_.push(temp);
     9                 if (temp->data_ < ptr_->data_){
    10                     //temp向右走说明temo指向的父节点不需要再次访问了
    11                     visited_.insert(temp);//add 2015.01.14
    12                     temp = temp->right_;
    13                 }
    14                 else if (temp->data_ > ptr_->data_){
    15                     temp = temp->left_;
    16                 }
    17             }
    18         }

    在初始化的过程中传入任意的树中节点指针ptr,然后从root开始沿着向下的方向用一个栈parent_来依次记录节点的父节点,同时我用一个set visited_来记录父节点相对于这个节点来说是否是已经访问过的状态,当节点处于这个父节点的右子树中时这个节点被记录。根据中序遍历的定义来看,当要访问任意节点的下一个节点的时候,如果节点还有右子树未访问则跳转到右子树的最小节点,当节点没有右子树的时候我们需要沿着父节点的顺序后退,此时不是所有的父节点都需要访问的,只有当节点处于父节点的左子树时,此时这个父节点才需要访问。

     1         template<class T>
     2         bst_iter<T>& bst_iter<T>::operator ++(){
     3             visited_.insert(ptr_);//此node被访问
     4             if (ptr_->right_){//此node还有右子树
     5                 //rvisited_.insert(ptr_);
     6                 parent_.push(ptr_);
     7                 ptr_ = ptr_->right_;
     8                 while (ptr_ && ptr_->left_){
     9                     parent_.push(ptr_);
    10                     ptr_ = ptr_->left_;
    11                 }
    12             }else{//node无右子树则只能向父节点路径移动
    13                 ptr_ = 0;//add 2015.01.14
    14                 while (!parent_.empty()){
    15                     ptr_ = parent_.top();
    16                     parent_.pop();
    17                     if (visited_.count(ptr_) == 0){//父节点尚未访问,此时ptr_指向此节点
    18                         visited_.insert(ptr_);
    19                         break;
    20                     }
    21                     ptr_ = 0;//设为哨兵
    22                 }//end of while
    23             }//end of if
    24             return *this;
    25         }

    第4-11行代码处理节点有右子树的情况。第12-23行代码处理节点无右子树需要向父节点移动的情况。

  • 相关阅读:
    牛客 动物园 (KMP)
    网络流模板与经典模型
    Codeforces Round #698 (Div. 2)
    CF1485X Codeforces Round #701
    CF1479B Painting the Array(贪心+DP)
    「AGC021E」Ball Eat Chameleons
    「AGC034E」 Complete Compress
    「AGC034D」 Manhattan Max Matching
    「ARC103D」 Distance Sums
    「AGC035C」 Skolem XOR Tree
  • 原文地址:https://www.cnblogs.com/zxh1210603696/p/4326857.html
Copyright © 2020-2023  润新知