红黑树,AVLTree树(平衡二叉树)迭代器原理讲解

        红黑树,AVLTree树底层实现逻辑都是平衡二叉树(AVLTree高度平衡,红黑树以某种规则平衡),但终究不像链表的迭代器那样逻辑简单。

        简单叙述以下,二叉树上面迭代器的运行逻辑,根据下面的图,迭代器的begin就是二叉树的最左节点,end是二叉树根节点的父节点(NULL)。

        为什么要这样设计,因为平衡二叉树在中序遍历下是升序排列,所以只有首部begin在二叉树最左节点,向后++遍历时,才能打印有序数据。

        但是为什么end在根节点的父亲?

        因为外部循环while(it!=end()),是不等于end节点,所以在遍历完右子树后就像上返回找类似于下图中绿色的parent节点了(右子树遍历完向上找),所以遍历完整颗二叉树后,就会向上找节点,到了父节点的父亲时就为空了,也就是end节点,所以就停止遍历了。

代码:

template<class T>
struct __TreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __TreeIterator<T> Self;
	Node* _node;//迭代器存的是二叉树的节点

	__TreeIterator(Node* node)
		:_node(node)
	{}

	T& operator*()
	{
		return _node->_data;
	}

	T* operator->()
	{
		return &_node->_data;
	}
    //这就是平衡二叉树迭代器的运行核心 一定要理解这部分逻辑才能理解好这个迭代器
	Self& operator++()
	{
		if (_node->_right)
		{
			// 下一个就是右子树的最左节点
			Node* cur = _node->_right;
			while (cur->_left)
			{
				cur = cur->_left;
			}

			_node = cur;
		}
		else
		{
			// 左子树 根 右子树
			// 右为空,找孩子是父亲左的那个祖先
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}

		return *this;
	}

    //给外界判断提供的
	bool operator!=(const Self& s)
	{
		return _node != s._node;
	}

	bool operator==(const Self& s)
	{
		return _node == s._node;
	}
};
	Self& operator--()
	{
		if (_node->_left)
		{
			Node* subRight = _node->_left;
			while (subRight->_right)
			{
				subRight = subRight->_right;
			}

			_node = subRight;
		}
		else
		{
			// 孩子是父亲的右的那个节点
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_left)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}

			_node = parent;
		}

		return *this;
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/137247.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode-链表经典题

1.反转单链表 206. 反转链表https://leetcode.cn/problems/reverse-linked-list/这里我们使用创建一个变量cur来遍历原链表&#xff0c;再创建一个新节点newnode&#xff0c;首先使用一个循环来遍历原链表&#xff0c;cur为NULL是循环结束&#xff0c;每次进入循环将cur的下一…

.mallab勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

导言&#xff1a; .mallab勒索病毒是一种极具威胁性的数字病毒&#xff0c;通过高级加密算法深度侵袭用户文件&#xff0c;迫使受害者支付赎金以获取解密密钥。了解其侵害方式和对抗手段对数字安全至关重要。数据的重要性不容小觑&#xff0c;您可添加我们的技术服务号&#x…

threejs(12)-着色器打造烟雾水云效果

一、自己封装水波纹效果 src/main/main01.js import * as THREE from "three";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import gsap from "gsap"; import * as dat from "dat.gui"; import ver…

【文件IO】

文章目录 File常见方法和属性属性构造方法方法 InputStream方法FileInputStream OutputStream利用 OutputStreamWriter 进行字符写入 总结按字节读取数据按字节写入数据按字符读取数据按字符写入数据 File常见方法和属性 属性 修饰符及类型属性说明static StringpathSeparato…

网络安全(黑客技术)-高效自学

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…

思科设备静态路由配置

一、静态路由基本知识 路由器的主要功能就是用来转发IP 数据包以使数据包到达正确的目的主机。可以想象数据包到达路由器就像一辆汽车开到十字路口&#xff0c;路由表就类似路标&#xff0c;列出可能到达的目的地&#xff0c;以及应该选择哪条路到达目的地。 路由器必须要有相应…

Linux - 基础IO(重定向 - 重定向模拟实现 - shell 当中的 重定向)- 下篇

前言 上一篇博客当中&#xff0c;我们对 文件 在操作系统当中是 如何就管理的&#xff0c;这个问题做了 详细描述&#xff0c;本篇博客将基于上篇 博客当中的内容进行 阐述&#xff0c;如有疑问&#xff0c;请参考上篇博客&#xff1a; Linux - 基础IO&#xff08;Linux 当中…

应用层——HTTP协议

文章目录 HTTP协议1.HTTP简介2.认识URL3.urlencode和urldecode4.HTTP协议格式&#xff08;1&#xff09;HTTP请求协议格式&#xff08;2&#xff09;HTTP响应协议格式 5.HTTP的方法6.HTTP的状态码7.HTTP常见的Header8.Cookie和Session HTTP协议 1.HTTP简介 HTTP&#xff08;Hy…

mac安装brew

命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"如图 选择下载源&#xff0c;进行安装 安装完成 验证

计算机毕业设计 基于SpringBoot的实训管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【零基础小白也能轻松学会】3DMAX编织建模教程

有没有想过这些木质材料是如何在椅子上相互交织的&#xff1f;复杂吗&#xff1f;也许是也许不是……本教程将指导您一步一步地以任何形式提出自己的复杂编织图案。本教程将重点关注建模部分&#xff0c;并让您从那里开始发挥想象力。 1.首先创建一个新平面&#xff08;长度55&…

C++: 内存管理 (new / delete)

文章目录 一. C/C 内存分布二. C 语言中动态内存管理方式: malloc/calloc/realloc/free三. C内存管理方式1. new / delete 操作内置类型2. new / delete 操作自定义类型 四. operator new 与 operator delete 函数五. new 和 delete 的实现原理1. 内置类型2. 自定义类型 六. 定…

【 第八章】软件设计师 之 计算机软件法律法规

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 备考资料导航 软考好处&#xff1a;软考的…

程序员的护城河:职业发展的关键元素

目录 1. 技术深度与广度 2. 项目经验与实际操作 3. 沟通与团队协作 4. 持续学习与自我更新 5. 社区参与与开源贡献 6. 创新思维与解决问题的能力 7. 职业规划与自我管理 结语 在科技日新月异的今天&#xff0c;程序员的竞争已经不再仅仅依赖于技术水平&#xff0c;而是…

路径总和[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在 根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和targetSum。如果存在&#xff0c;返回true&#xff1b;否则&#xff0c;返回fa…

基于SpringMVC模式的电器网上订购系统的设计

大家好我是玥沐春风&#xff0c;今天分享一个基于SpringMVC模式的电器网上订购系统的设计&#xff0c;项目源码以及部署相关请联系我&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 本系统利用现在比较广泛的JSP结合后台SpringMybatisAjax编写程序的方式实现的。 在…

【C++入门】构造函数析构函数

目录 前言 1. 类的默认成员函数 2. 构造函数 2.1 什么是构造函数 2.2 构造函数的特性 3. 析构函数 3.1 什么是析构函数 3.2 析构函数的特性 前言 前边我们已经了解了类和对像的基本概念&#xff0c;今天我们将继续深入了解类。类有6个默认成员函数&#xff0c;即使类中什么都…

Golang 字符串处理汇总

1. 统计字符串长度&#xff1a;len(str) len(str) 函数用于统计字符串的长度&#xff0c;按字节进行统计&#xff0c;且该函数属于内置函数也不用导包&#xff0c;直接用就行&#xff0c;示例如下&#xff1a; //统计字符串的长度,按字节进行统计: str : "golang你好&qu…

【数据库开发】DataX开发环境的安装部署(Python、Java)

文章目录 1、简介1.1 DataX简介1.2 DataX功能1.3 支持的数据通道 2、DataX安装配置2.1 DataX2.2 Java2.3 Python 3、DataX Web安装配置3.1 mysql3.2 DataX Web3.2.1 简介3.2.2 架构图3.2.3 依赖环境3.2.4 安装 4、入门使用4.1 DataX自带打印示例测试4.2 DataX生成任务模板文件4…

Leetcode—234.回文链表【简单】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—234.回文链表 直接法实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ bool isPalindrome(struct ListNode* head) {if(head NULL) {return t…