平衡二叉树的构建(理论,部分函数代码)

news2024/11/18 3:44:03

        平衡二叉树是二叉排序树的一种特殊情况,平衡二叉树的出现是为了在最坏情况下的时间复杂度仍然是对数级别O(logn),从而保证了高效的搜索、插入和删除操作。

举个例子,如果有一个数组是:1,2,3。如果只简单的排序:

        如图所示,如果想要找到 3 这个元素,那么需要寻找 3 次,比较麻烦,如果换一种排序方式,如第二张图,仍然是二叉排序树,但是这次只需要寻找 2 次即可。

平衡二叉树(AVL)的特点是:

每个节点的左右子树的高度差最多为 1 。

        那么如何实现左右子树的高度差只有 1 呢?这就需要引出文章的内容:四种操作,让普通排序二叉树变成平衡二叉树。

第一种,左旋(Left Rotation)

        这种操作通常在左子树较高的情况下发生,如图,3 节点的左子树高度是2,右子树高度为0。我们要实现左图到右图的转变。

        图中的方块是 2 节点的右子树,可以为空,如果存在,既然方块一开始就在 3 节点的左子树上,所以方块最后也一定在 3 的左子树。

        现在我们可以思考一下具体操作,首先,把 2 的右孩子连接到 3 节点上(无论是否为空),然后把原来的根节点(3节点)连接到 2 节点上,最后更新根节点(变为 2 节点)。

代码如下:

void LL( TreeNode** root) {
	TreeNode* node = NULL;
	node = (*root)->lchild;
	(*root)->lchild = node->rchild;
	node->rchild = (*root);
	(*root)->height = Max(GetTreeHeight((*root)->lchild), GetTreeHeight((*root)->rchild)) + 1;
	node->height = Max(GetTreeHeight(node->lchild), GetTreeHeight(node->rchild)) + 1;
	*root = node;
}

        关于 Max 函数和 GetTreeHeight 函数我下篇文章会详细讲解,首先因为最后要改变根节点指针,所以传二级指针来改变根节点指针的值。旋转代码的关键就四行代码,红色箭头是找到 node 节点,即新的根节点,蓝色圈代表子树的重新构建,绿色箭头是代码的执行顺序。

第二种, 右旋(Right Rotation)

同理,右旋主要发生在右子树比较高的情况下,也就是文章最开始的图例。具体流程如下

        和左旋的原理一模一样,先把 2 节点的左孩子连接到原根节点上,然后把原根节点连接到 2 节点上,然后更新根节点,使 2 节点更新为新根节点,代码如下:

void RR( TreeNode** root) {
	TreeNode* node = NULL;
	node = (*root)->rchild;
	(*root)->rchild = node->lchild;
	node->lchild = (*root);
	(*root)->height = Max(GetTreeHeight((*root)->lchild), GetTreeHeight((*root)->rchild)) + 1;
	node->height = Max(GetTreeHeight(node->lchild), GetTreeHeight(node->rchild)) + 1;
	*root = node;
}

下面是过程图,逻辑和左旋相同,先保留 2 的左节点,更新 2 的左节点,最后更新根节点。

第三种,左-右旋(Left-Right Rotation)

        如果二叉树是这种情况,此时 4 节点的左孩子高度为2,右孩子高度为0,此时需要变成右图中的情况。

        具体操作就是,把 2 节点连接到 3 节点的左孩子,4 节点连接到 3 节点的右孩子,最后更新根节点,使 3 节点变为根节点。

void LR(TreeNode** root) {
	TreeNode* node = NULL;
	node = (*root)->lchild->rchild;
	node->lchild = (*root)->lchild;
	node->rchild = *root;
	(*root)->height = Max(GetTreeHeight((*root)->lchild), GetTreeHeight((*root)->rchild)) + 1;
	node->height = Max(GetTreeHeight(node->lchild), GetTreeHeight(node->rchild)) + 1;
	*root = node;
}

下面是左右旋的流程图: 

 第四种,右-左旋(Right-Left Rotation)

        第四种和第三种原理一样,只不过变成,把 4 节点连接到 3 节点的右孩子,2 节点连接到 3 节点的左孩子,最后更新根节点。

最后直接附上代码了:

void RL(TreeNode** root) {
	TreeNode* node = NULL;
	node = (*root)->rchild->lchild;
	node->lchild = *root;
	node->rchild = (*root)->rchild;
	(*root)->height = Max(GetTreeHeight((*root)->lchild), GetTreeHeight((*root)->rchild)) + 1;
	node->height = Max(GetTreeHeight(node->lchild), GetTreeHeight(node->rchild)) + 1;
	*root = node;
}

这就是文章的全部内容了,希望对你有所帮助,如有错误欢迎评论。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库多表查询

多表查询: SELECT *FROM stu_table,class WHERE stu_table.c_idclass.c_id; 多表查询——内连接 查询两张表交集部分。 隐式内连接: #查询学生姓名,和班级名称,隐式调用 SELECT stu_table.s_name,class.c_name FROM stu_table…

vs code 中使用SSH 连接远程的Ubuntu系统

如下图,找到对应的位置 在电脑上找到以下位置 打开配置如下,记住,那个root为你的用户名,这个用户名,具体根据你的用户名来设置,对应的密码就是你登录Ubuntu时的密码 Host root192.168.0.64User rootHostNa…

文件跨境传输法律管控越来越严格,企业该如何有效应对?

文件跨境传输已经成为非常普遍的业务需求,企业在世界各地的总分支处、合作伙伴,客户间开展业务时,必须基于数据的跨境流转而展开。 但随着世界各国对数据安全的重视,文件跨境传输也日趋严格,各国在法律法规上均出具了更…

RP2040 SPI DMA驱动ST7735

SPI DMA演示 一、源码 #include <stdio.h> #include <stdlib.h> #include "pico/stdlib.h" #include "pico/binary_info.h" #include "hardware/spi.h" #include "hardware/dma.h" #include "font.h"#define X…

Ownips+Coze海外社媒数据分析实战指南

目录 一、引言二、ISP代理简介三、应用实践——基于Ownips和coze的社媒智能分析助手3.1、Twitter趋势数据采集3.1.1、Twitter趋势数据接口分析3.1.2、Ownips原生住宅ISP选取与配置3.1.3、数据采集 3.2、基于Ownips和Coze的社媒智能助手3.2.1、Ownips数据采集插件集成3.2.2、创建…

Ubuntu配置Git

安装git sudo apt install git 查看是否安装成功 git --version 配置git 用github上注册的用户名和邮箱地址&#xff0c;配置git git config --global user.name "username" git config --global user.email "usernameemail.com" 重启ubuntu查看…

首搭第五代DM技术,秦L DM-i正式上市,仅售9.98万元起

5月28日&#xff0c;比亚迪王朝重磅新车秦L DM-i在西安震撼上市&#xff0c;首搭第五代DM技术&#xff0c;百公里亏电油耗达到划时代的2.9L&#xff0c;“一箱油”满油满电综合续航达2100公里&#xff0c;引领中级&#xff0c;创下了百公里油耗的历史新低&#xff0c;开创油耗2…

机顶盒也可以跑pcdn--上机指南(贰)

机顶盒能跑PCDN&#xff0c;以下是相关上机指南操作步骤&#xff1a; 1.申请PCDN服务&#xff1a;登录PCDN控制台&#xff0c;申请开通PCDN服务。 2.后台开通PCDN服务&#xff1a;工作人员与用户沟通业务详细需求&#xff0c;用户确定使用PCDN&#xff0c;后台为用户开通PCDN…

VolWeb:集中式增强型数字取证内存分析平台

关于VolWeb VolWeb是一款最新开发的集中式增强型数字取证内存分析平台&#xff0c;该平台基于Volatility 3框架实现其功能&#xff0c;该工具旨在辅助广大研究人员执行安全分析和事件应急响应等任务。 VolWeb可以提供集中式、可视化的增强型网络应用程序&#xff0c;并提高安全…

Java基础:类的详细说明

Java是一门面向对象的编程语言&#xff0c;所谓的面向对象&#xff0c;简单的说&#xff0c;就是在软件开发过程中&#xff0c;用各种各样的对象实现所需功能。 对象就好像是现实世界中不计其数的物体&#xff0c;根据物体的性质可以将其进行分门别类&#xff1a;石头、锤子、…

深入分析 Android Activity (十一)

文章目录 深入分析 Android Activity (十一)1. Activity 的内存管理和优化1.1 内存泄漏的常见原因1.2 避免内存泄漏的方法1.3 内存泄漏检测工具 2. Activity 的配置变更处理2.1 处理配置变更2.2 保存和恢复状态2.3 使用 ViewModel 3. Activity 的测试3.1 单元测试3.2 UI 测试 4…

编译安装Apache httpd服务(LAMP1)

目录 1.初始化设置&#xff0c;将Apache所需软件包传到 /opt 目录下 &#xff08;1&#xff09;关闭防火墙 &#xff08;2&#xff09;上传软件包到/opt目录 2.安装环境依赖包 3.配置软件模块 4.编译及安装 5.优化配置文件路径&#xff0c;并把httpd服务的可执行程序文件…

DDR5芯片系统框图详解

DDR5 SDRAM(双倍数据率五代同步动态随机存取存储器)的功能框图详细展现了其内部结构和各个关键模块,这些模块协同工作以实现高速数据传输和存储管理。以下是主要组成部分的详细介绍: Controller Logic (控制器逻辑)这是DDR5内存系统的大脑,负责接收来自CPU或SoC的指令,解…

怎么从视频中截取图片?这3个视频截图方法超清晰

怎么从视频中截取图片&#xff1f;从视频中截取图片确实是一个不可或缺的技能&#xff0c;特别是在我们想要留住视频中的某个动人瞬间、重要细节或是用于制作海报、封面等场合时。无论是专业的视频编辑人员&#xff0c;还是普通用户&#xff0c;掌握这技巧都能让视频内容得到更…

光缆监测主要功能值得一看

网络资源管理&#xff1a; 设备管理&#xff1a; 测试告警处理&#xff1a; 百度地图&#xff1a; 报表打印&#xff1a; 路由测试数据、路由段数据、路由故障报警统计、当前故障通知情况、路由测试数据、路由段信息。 手机客户端&#xff1a; 通过手机可以访问系统&#x…

为WPF的Grid添加网格边框线

在WPF中使用Grid绘制表格的时候&#xff0c;如果元素较多、排列复杂的话&#xff0c;界面会看起来很糟糕&#xff0c;没有层次&#xff0c;这时用网格或边框线分割各元素&#xff08;标签或单元格&#xff09;将会是页面看起来整齐有条理。 默认没有边框线的如下图所示&#xf…

FuTalk设计周刊-Vol.049

#AI漫谈 热点捕手 1.Gemini Pro1.5及其百万上下文功能现已向所有人开放 Gemini Pro1.5加入视频模态的长上下文功能&#xff0c;AI可以处理更复杂的视频内容。 链接https://aistudio.google.com/app/prompts/new_chat?reftop.aibase.com 2.Figma 2024 Config 大会 6月26-27日…

Java - 当年很流行,现在已经淘汰的 Java 技术,请不要在继续学了!!!

最近这段时间收到了一些读者的私信&#xff0c;问我某个技术要不要学&#xff0c;还有一些在国外的同学竟然对 Java 图形化很感兴趣&#xff0c;还想找这方面的工作。 比较忙&#xff0c;一直没抽出时间去回答这类问题&#xff0c;刚好看到我关注的一位大佬回答过&#xff0c;这…

着色器技术在AI去衣中的魔法般的作用

引言&#xff1a; 在数字图像处理的世界中&#xff0c;AI去衣技术正逐步成为研究的前沿。它利用人工智能的强大能力&#xff0c;实现对图像中衣物的智能识别与处理。在这一过程中&#xff0c;着色器&#xff08;Shader&#xff09;技术扮演了至关重要的角色。本文将深入探讨着色…

笔记-python-map的用法

map()函数 map()是 Python 内置的高阶函数&#xff0c;它接收一个函数 f 和一个 list&#xff0c;并通过把函数 f 依次作用在 list 的每个元素上&#xff0c;得到一个新的 list 并返回。 1、当seq只有一个时&#xff0c;将函数func作用于这个seq的每个元素上&#xff0c;并得到…