当前位置: 首页 > news >正文

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

之前在完成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行代码处理节点无右子树需要向父节点移动的情况。

转载于:https://www.cnblogs.com/zxh1210603696/p/4326857.html

相关文章:

  • POJ 1984
  • Ubuntu 配置开机启动到字符界面
  • 【监控】天机镜——优土大数据平台应用级别监控利器
  • Webpack - CommonJs AMD 模块打包器
  • 浅谈Swift语法
  • 开通博客园
  • 简谈软件测试
  • Android更新UI的五种方式
  • 构造函数实例化
  • Lintcode: Merge Sorted Array II
  • C++ 常量类型 const 详解
  • 创建非arc的项目
  • processing fill()和stroke()函数
  • C++移位运算符
  • Android 如何通过 Windows 录制视频
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • Android框架之Volley
  • Angularjs之国际化
  • Javascript设计模式学习之Observer(观察者)模式
  • laravel5.5 视图共享数据
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Nodejs和JavaWeb协助开发
  • Otto开发初探——微服务依赖管理新利器
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • python学习笔记-类对象的信息
  • 从零开始的无人驾驶 1
  • 前端临床手札——文件上传
  • 前端学习笔记之观察者模式
  • 深度学习在携程攻略社区的应用
  • 事件委托的小应用
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 小程序 setData 学问多
  • 移动端唤起键盘时取消position:fixed定位
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 用element的upload组件实现多图片上传和压缩
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​力扣解法汇总946-验证栈序列
  • #预处理和函数的对比以及条件编译
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二十四)Flask之flask-session组件
  • (十五)使用Nexus创建Maven私服
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (原)本想说脏话,奈何已放下
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .apk 成为历史!
  • .NET Core引入性能分析引导优化
  • .net6使用Sejil可视化日志
  • .NET学习全景图
  • .NET中使用Protobuffer 实现序列化和反序列化
  • @Bean, @Component, @Configuration简析
  • @基于大模型的旅游路线推荐方案
  • [2010-8-30]