你真的懂树的平衡吗?深入剖析C语言中左右旋转的核心逻辑

第一章:树的平衡本质与二叉查找树的挑战

在计算机科学中,树结构是组织和管理数据的重要工具。其中,二叉查找树(Binary Search Tree, BST)因其高效的查找、插入和删除操作而被广泛使用。其核心特性在于:对于任意节点,左子树所有节点值小于该节点值,右子树所有节点值大于该节点值。

二叉查找树的性能依赖于结构平衡

理想情况下,BST 的操作时间复杂度为 O(log n),前提是树的高度保持对数级别。然而,当插入的数据呈有序或近似有序时,BST 可能退化为链表结构,导致最坏情况下的时间复杂度上升至 O(n)。例如,依次插入 1, 2, 3, 4, 5 将形成一条向右延伸的斜链。
  • 插入顺序影响树的高度
  • 不平衡的树降低查询效率
  • 动态数据环境下难以手动维持平衡

平衡树的设计动机

为了克服这一缺陷,引入了“平衡”概念——通过旋转等机制自动调整结构,确保任意节点左右子树高度差控制在一定范围内。AVL 树和红黑树便是典型代表。 以下是一个简单的二叉查找树插入逻辑示例:
// Insert 插入一个值到 BST 中
func (t *TreeNode) Insert(val int) {
    if val < t.Val {
        if t.Left == nil {
            t.Left = &TreeNode{Val: val}
        } else {
            t.Left.Insert(val) // 递归插入左子树
        }
    } else {
        if t.Right == nil {
            t.Right = &TreeNode{Val: val}
        } else {
            t.Right.Insert(val) // 递归插入右子树
        }
    }
}
该代码未包含平衡操作,因此在特定输入下会导致性能下降。真正的平衡树需在每次插入或删除后检测并修复失衡状态。
树类型平衡策略平均时间复杂度
普通 BST无O(log n)
AVL 树严格高度平衡O(log n)
红黑树颜色标记+旋转O(log n)
graph TD A[根节点] --> B[左子树] A --> C[右子树] B --> D[值小于根] C --> E[值大于根]

第二章:左旋转的核心机制与实现

2.1 左旋转的理论基础与适用场景

左旋转是二叉树结构中一种重要的动态调整操作,主要用于维持树的平衡性。在AVL树或红黑树等自平衡二叉搜索树中,当右子树高度显著大于左子树时,通过左旋转将右孩子提升为新的根节点,原根节点成为其左孩子,从而恢复平衡。
左旋转的基本条件
  • 当前节点的右子树“过重”
  • 插入或删除操作破坏了平衡因子
  • 需要维持O(log n)的查找性能
代码实现示例
func leftRotate(node *TreeNode) *TreeNode {
    newRoot := node.Right
    node.Right = newRoot.Left
    newRoot.Left = node
    // 更新高度
    node.height = max(height(node.Left), height(node.Right)) + 1
    newRoot.height = max(height(newRoot.Left), height(newRoot.Right)) + 1
    return newRoot
}
上述函数执行一次标准左旋转:将node的右孩子newRoot上移,原节点变为左子节点。旋转后需重新计算节点高度以维护平衡信息。该机制广泛应用于数据库索引、文件系统等对查询效率敏感的场景。

2.2 节点结构设计与指针重连原理

在分布式系统中,节点结构的设计直接影响系统的可扩展性与容错能力。每个节点通常包含唯一标识、状态信息及指向相邻节点的指针,形成逻辑拓扑。
节点基本结构
type Node struct {
    ID       string            // 节点唯一标识
    Address  string            // 网络地址
    Peers    map[string]*Node  // 邻居节点指针映射
    Status   int               // 节点运行状态
}
该结构通过指针(*Node)实现节点间的动态关联,避免数据复制开销。Peers字段维护了动态连接关系,支持运行时重连。
指针重连机制
当网络分区恢复或节点重启后,系统触发指针重连流程:
  1. 节点广播自身状态至注册中心
  2. 获取最新节点列表并建立TCP连接
  3. 更新本地Peers指针映射,释放无效引用
此过程确保拓扑最终一致性,提升系统自愈能力。

2.3 基于C语言的左旋转代码实现

在字符串处理中,左旋转操作是指将字符串前若干个字符移到末尾。该操作可通过数组下标映射高效实现。
算法思路
通过三次反转实现左旋:先反转前n个字符,再反转剩余部分,最后整体反转。时间复杂度为O(n),空间复杂度为O(1)。
核心代码实现

void reverse(char* s, int start, int end) {
    while (start < end) {
        char temp = s[start];
        s[start++] = s[end];
        s[end--] = temp;
    }
}

void leftRotate(char* s, int n, int len) {
    if (n >= len || n <= 0) return;
    reverse(s, 0, n - 1);     // 反转前n个
    reverse(s, n, len - 1);   // 反转后续
    reverse(s, 0, len - 1);   // 整体反转
}
上述代码中,reverse 函数用于区间反转,leftRotate 执行三步反转完成左移。参数 n 表示旋转位数,len 为字符串长度。

2.4 边界条件处理与空指针防御

在系统开发中,边界条件处理是确保程序稳定运行的关键环节。未正确校验输入或资源状态极易引发空指针异常,进而导致服务崩溃。
常见空指针场景
  • 调用未初始化对象的方法
  • 访问数组或集合的空引用
  • 方法返回null但未做判空处理
防御式编程示例
func GetUserAge(user *User) int {
    if user == nil || user.Profile == nil {
        return -1 // 返回默认值或错误码
    }
    return user.Profile.Age
}
上述代码通过双重判空避免了空指针异常,优先检查user对象本身,再验证其嵌套字段Profile的有效性,体现了由外至内的安全校验逻辑。
推荐处理策略
策略说明
前置校验函数入口处统一检查参数合法性
默认值返回避免抛出异常,提升容错能力

2.5 左旋转后的树结构验证与调试

在完成左旋转操作后,必须对树的结构进行完整性验证,确保二叉搜索树性质未被破坏。
结构一致性检查
通过中序遍历确认节点顺序是否保持升序:
// 中序遍历验证BST性质
func inorder(root *TreeNode) []int {
    var res []int
    var dfs func(*TreeNode)
    dfs = func(node *TreeNode) {
        if node != nil {
            dfs(node.Left)
            res = append(res, node.Val)
            dfs(node.Right)
        }
    }
    dfs(root)
    return res
}
该函数输出节点值序列,若非升序则说明旋转逻辑有误。
高度与平衡因子校验
使用递归计算各子树高度,并验证平衡因子绝对值不超过1:
  • 空节点高度定义为-1
  • 非空节点高度为 max(左子树高, 右子树高) + 1
  • 平衡因子 = 左子树高 - 右子树高

第三章:右旋转的对称逻辑与应用

3.1 右旋转的几何直观与数学依据

右旋转是二叉搜索树维持平衡的核心操作之一,常用于AVL树或红黑树中。从几何角度看,右旋转相当于以某节点为支点,将其左子节点“下拉”成为新的根节点,原根节点则作为其右子树的一部分下沉。
旋转前后的结构变化
  • 设节点 A 为旋转中心,其左子节点为 B
  • 右旋转后,B 成为新的根,A 成为 B 的右子节点
  • B 的原右子树变为 A 的左子树
// 右旋转示例代码(简化版)
func rightRotate(a *Node) *Node {
    b := a.left
    a.left = b.right
    b.right = a
    // 更新高度(如AVL树)
    a.height = max(height(a.left), height(a.right)) + 1
    b.height = max(height(b.left), height(b.right)) + 1
    return b // 新的根节点
}
上述代码实现右旋转:将 a 的左子节点 b 提升,并调整指针关系。参数 a 为待旋转节点,返回值为新的子树根节点。关键在于指针重连顺序,避免循环引用。
图表示意:右旋转前后子树结构重构,保持中序遍历不变

3.2 C语言中右旋转的递归与迭代实现

右旋转操作的基本概念
在二叉树结构中,右旋转常用于平衡操作,如AVL树或红黑树。它通过调整节点间的父子关系,降低树的高度,提升查找效率。
递归实现方式
struct TreeNode* rightRotate(struct TreeNode* y) {
    struct TreeNode* x = y->left;
    struct TreeNode* T2 = x->right;

    x->right = y;
    y->left = T2;

    return x; // 新的子树根
}
该函数将节点 y 向右旋转,x 成为新的根,T2 作为 y 的左子树,保持BST性质。
迭代实现对比
  • 递归实现简洁,逻辑清晰,适合理解旋转本质;
  • 迭代方式需手动维护父节点指针,适用于栈空间受限场景;
  • 两者时间复杂度均为 O(1),但递归有函数调用开销。

3.3 旋转后二叉查找树性质的保持验证

在对二叉查找树执行左旋或右旋操作后,必须确保中序遍历的有序性依然成立。旋转操作仅改变节点间的父子关系,不改变其逻辑顺序。
旋转操作的核心约束
  • 左旋时,右子节点提升为父节点,原父节点成为其左子节点;
  • 右旋时,左子节点上移,原父节点变为右子节点;
  • 所有节点的左子树值仍小于根,右子树值大于根。
代码实现与验证

func rotateRight(x *Node) *Node {
    y := x.left
    x.left = y.right
    y.right = x
    // 更新高度(若为AVL树)
    x.height = max(height(x.left), height(x.right)) + 1
    y.height = max(height(y.left), height(y.right)) + 1
    return y // 新的子树根
}
上述函数执行右旋后,通过重新计算节点高度维持平衡信息,且不会破坏BST的键值顺序。中序遍历时,原序列顺序不变,仅结构调整。

第四章:双旋转与AVL树的自平衡策略

4.1 左-右双旋转的分解与合成逻辑

在AVL树的平衡调整中,左-右双旋转是一种复合操作,用于处理左子树过高且其右子树过重的情形。该操作可分解为先对左子树执行左单旋,再对根节点执行右单旋。
旋转步骤分解
  1. 对根节点的左子节点进行左单旋转,提升其右子树高度;
  2. 对原根节点执行右单旋转,恢复整体平衡。
代码实现

// 右旋转函数(简化示意)
Node* rotateRight(Node* y) {
    Node* x = y->left;
    y->left = x->right;
    x->right = y;
    updateHeight(y);
    return x;
}
上述代码展示右旋转核心逻辑:通过指针重连将左子节点提升为新根,并更新父子关系与高度信息,确保BST性质不变。

4.2 右-左双旋转的实际应用场景分析

在AVL树的动态插入场景中,当右侧子树先发生左高倾斜,再导致整体右倾时,需触发右-左双旋转。该操作常见于数据库索引结构的自平衡维护。
典型触发条件
  • 节点插入至右子节点的左子树
  • 右子树的平衡因子为 -1
  • 当前节点平衡因子达到 -2
旋转步骤与代码实现

func rightLeftRotate(node *Node) *Node {
    node.right = rightRotate(node.right)
    return leftRotate(node)
}
上述代码先对右子节点执行右单旋,恢复其内部平衡,再对根节点左旋,恢复整体高度平衡。两次旋转后,树高最多增加1,确保查询效率稳定在 O(log n)。

4.3 AVL树插入操作中的自动平衡触发

平衡因子与旋转机制
AVL树在每次插入节点后会更新祖先节点的平衡因子,当某节点的平衡因子绝对值超过1时,即触发旋转操作以恢复平衡。
  • 左旋(Right Rotation):适用于右子树过高的情况
  • 右旋(Left Rotation):适用于左子树过高的情况
  • 双旋:如左右型或右左型失衡时组合使用
插入后平衡判断示例

if (balance > 1 && key < node->left->key)
    return rightRotate(node); // 右旋
else if (balance < -1 && key > node->right->key)
    return leftRotate(node);  // 左旋
上述代码判断是否发生左-左或右-右失衡,并执行对应单旋。key为插入值,node为当前根节点,balance为平衡因子。
失衡类型触发条件处理方式
LL型左子树过高,新节点在左侧右旋
RR型右子树过高,新节点在右侧左旋

4.4 平衡因子计算与高度更新的同步机制

在AVL树中,节点的平衡因子依赖于左右子树的高度差,因此每次插入或删除操作后必须同步更新高度与平衡因子。
数据同步机制
节点高度应在递归回溯过程中自底向上更新,确保父节点高度基于最新子树高度计算。平衡因子随之重新计算,以判断是否失衡。

func updateHeight(node *TreeNode) {
    leftHeight := height(node.Left)
    rightHeight := height(node.Right)
    node.Height = max(leftHeight, rightHeight) + 1
}

func getBalance(node *TreeNode) int {
    if node == nil {
        return 0
    }
    return height(node.Left) - height(node.Right)
}
上述代码中,updateHeight 确保当前节点高度为子树最大高度加一;getBalance 利用更新后的高度计算平衡因子,保障后续旋转判断的准确性。
更新顺序的重要性
  • 先递归处理子树
  • 再更新当前节点高度
  • 最后计算平衡因子并决定旋转

第五章:从旋转到高性能树结构的设计哲学

平衡的艺术:AVL 与红黑树的抉择
在高并发数据处理中,选择合适的自平衡二叉搜索树至关重要。AVL 树通过严格的平衡条件确保 O(log n) 的查找性能,适用于读密集场景;而红黑树以较少的旋转操作换取近似平衡,更适合频繁插入删除的混合负载。
  • AVL 树每次插入可能触发 O(log n) 次旋转
  • 红黑树最多只需两次旋转即可恢复性质
  • MySQL 索引使用 B+ 树,Redis 有序集合底层为跳跃表
实战中的优化策略
考虑一个实时推荐系统中的用户行为索引构建,需快速定位最近 K 小评分项。采用定制化伸展树(Splay Tree),将热点节点自动上浮至根部:

func (t *SplayTree) Access(key int) {
    t.root = t.splay(t.root, key)
    // 热点访问自动提升,局部性优化
}
树类型平均插入最差查找适用场景
AVL TreeO(log n)O(log n)静态查询为主
Red-Black TreeO(log n)O(log n)动态更新频繁
现代架构下的演进方向
[Root] / \ [Left] [Right] | | Cache-A Cache-B (Hot) (Warm)
面对多级缓存体系,树结构设计需融合访问频率预测机制,实现数据热度感知的动态再平衡。
产业园区如何高效对接企业技术需求与高校科研成果?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

相关推荐

4 轴穿越机 Mark5 机架全解析:从历史演进到电机桨叶选型指南

本文围绕 4 轴穿越机 Mark5 机架展开,先介绍其发展历程(2018 年初代到 2023 年五代,迭代优化轻量化、刚性与兼容性),再明确其核心参数(轴距 220mm、兼容 4-6 寸桨等)对电机桨叶的约束。 详解电机(KV 值、尺寸、推力等)与桨叶(尺寸、螺距、材质等)选型要点及匹配原则(高 KV 配小桨、低 KV 配大桨),给出推重比、功率等理论计算公式,结合新手练习、花飞、竞速、航拍等场景提供具体选型案例,最后提及安全、成本、法规等注意事项,为爱好者提供全面选型参考。

bother3000的博客 1901

树的四种平衡处理方式

平衡二叉树的四种平衡处理

Black_vv的博客 564

发那科机器人抓手与物料搬运阀的配置与优化实践

本文详细介绍了发那科机器人抓手与物料搬运阀的配置与优化实践,包括基础配置指南、阀岛与输入模块的详细设置、测试程序编写与验证技巧,以及常见问题排查与性能优化建议。通过实际案例和经验分享,帮助技术人员快速掌握关键配置步骤,提升物料搬运系统的稳定性和效率。

weixin_33738555的博客 385

数据结构之平衡二叉树的平衡调整

本文章主要说明平衡二叉树的平衡调整,即LL型,RR型,LR型,RL型调整方法,和在程序中如何判断不平衡类型是LL型,RR型,LR型还是RL型

qq_57541265的博客 7195

Flutter热更新实战:Shorebird从安装到发布补丁的完整流程(含iOS/Android差异解析)

本文详细介绍了Flutter热更新工具Shorebird的完整使用流程,包括安装、发布补丁及iOS/Android平台差异解析。Shorebird作为Flutter官方未提供的Code Push解决方案,能快速修复线上问题,支持合规性保障和性能优化,特别适合紧急修复场景。文章还涵盖了国内CDN加速配置和最佳实践,帮助开发者高效实现热更新。

butter的博客 1079

破局KS滑块验证码:从参数加密到轨迹生成,Python逆向全流程避坑实录

快手滑块验证码破解实战:从逆向分析到自动化实现 摘要:本文详细记录了破解快手滑块验证码(KS滑块)的完整过程。通过48小时的逆向分析,揭示了KS滑块的双重校验机制:不仅需要精准定位滑块缺口位置,还需满足参数加密和轨迹特征校验。文章从反爬逻辑分析入手,介绍了工具选型与环境配置的避坑要点,重点讲解了滑块缺口距离计算方法和核心加密参数slide_sign的逆向过程。通过OpenCV边缘检测和Frida动态调试技术,成功实现了滑块验证的自动化,准确率提升至99%。文中附有Python实现代码和实际操作踩坑记录,为开

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1662

数据结构之——平衡二叉树(内容详解)

一、基本概念 平衡二叉树也叫AVL树,它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和左子树的高度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。 二、结构 如基本概念所树,它具有一个左子树和一个左子树,且对于任意一个子树而言,左子树和右子树高度只差不超过1. 2.1 平衡二叉树判别 如下有3棵树,分别判断下哪个是平衡二叉树? 图1: 图2:...

m0_37914588的博客 11万+

Openclaw第5章 知识库管理

💡:学会使用 OpenClaw构建个人知识库系统,实现网页文章存档、GitHub项目管理、论文笔记整理和跨设备同步。

Maynor的博客 776

平衡树概述

平衡树是排序二叉树的(SBT)的升级版。就是采取各种手段让排序二叉树变得更平衡,不然在数据极端的情况下,SBT退化成一条链,复杂度也退化成n2n2n^2了。总的来说,就是为了不被丧病出题人卡极端数据发明的算法。 \\ 我们直接把三种写法放在一起(可能会有点长,不过将就看吧)。 平衡树——替罪羊树概述 自从写了平衡树之后就整个人都不好了,我是个蒟蒻,打个200行的代码就不咋调得出来。...

lvmaooi的博客 2124

别再只会复制Haar级联代码了!OpenCV人脸检测全方案深度解析,从原理到工业级落地

通用预训练模型在你的业务场景效果不好时,用自己的业务数据集训练专属的级联器,是提升精度的终极方案,OpenCV自带和工具,支持自定义Haar/LBP级联器训练。场景首选方案次选方案新手入门学习Haar级联分类器LBP级联分类器嵌入式轻量固定场景LBP级联分类器YuNet轻量版工业级落地项目(99%场景)DNN+YuNetMTCNN多人脸+小目标复杂场景DNN+YuNet自定义微调模型同时做人脸+其他目标检测。

2601_94871597的博客 379

MIMIC数据库简介

一 、MIMIC简介 MIMIC(Medical Information Mart for Intensive Care),是一个大型的公开数据库。该数据库记录了2001年至2019年期间贝斯以色列女狄肯斯医疗中心重症监护病房患者的相关数据,拥有4万多名患者的医疗健康数据和记录。 MIMIC数据库记录了人口统计学信息,如病人的性别、身高、宗教等情况。记录了实验室检验信息,如血常规,肝功能,肾功能等实验室检测数据。记录了患者的用药信息,如高血压患者服用了治疗高血压类药物等。记录了护理人员以及患者的护理级别等。

越努力 越幸运 1万+

平衡树基础2——AVL树

/结构定义int key, h;//多了一个h存储树高}Node;//几个方便的宏//创建一个虚拟空节点Node __NIL;//这个作用是规定下面函数的性质,可以让他先于主函数执行//但是我这个编译器不支持,还是要放到主函数中调用。NIL->h = 0;return;1.要学习左旋、右旋这两个二叉树平衡调整的重要操作。2.可以借鉴虚拟空节点这个编程技巧3.测试时的输出更能体现编程能力,学习type_str这个技巧4.要记住AVL树的平衡和失衡条件。

2301_80216298的博客 636

基于轻量化网络的干扰信号智能识别算法

针对干扰信号识别时卷积神经网络模型体积大、训练周期长、对硬件存储和计算要求高等问题,本 文提出了一种基于改进轻量级网络模型 SqueezeNet 的干扰信号智能识别算法。该方法首先利用距离多普勒 (Range‑Doppler,RD)处理获得目标及干扰信号的RD图像,接着采用滑窗变换、归一化等技术对RD图像进行重 塑;然后采用基于 RD 信息尺寸的隐层和通道剪枝措施对 SqueezeNet 网络进行改进,缩小了模型尺寸和存储空 间;最后利用不同参数的测试样本拓展网络模型的泛化性能。

qq_43416206的博客 545

平衡二叉树(原理)

关于是哪一种型,其实就是根据插入的新节点与最小不平衡子树的根节点的位置关系决定的,如果你往左孩子里插入,所以你就是个Lx型,如果插入在右孩子上就是Rx型,接下来再看你插入的是左孩子的左子树还是右子树决定用LR型还是LL型,如果你插入的节点是在右孩子的左子树或者右子树上,就决定了要用RL型还是RL型接下来我们构建一个平衡二叉树,把这四种情况加深一下印象。

weixin_73266891的博客 981

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

树的旋转

在学习红黑树,树堆,平衡树的时候我们经常会看到一个树的操作---旋转。树的旋转之前也只是机械记忆而已,但机械记忆的东西终归不是自己的,这说明自己没有理解到其中的精髓。 定义:树旋转是二叉树中一种子树调整操作,每一次旋转不会影响二叉树的中序遍历结果。 二叉树的中序遍历结果可以用投影的方式快速得到,如图所示: 如果这是一颗搜索树,那么中序遍历的顺序一定是自小而大的,这...

diaozhihou4913的博客 252

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

动图详解平衡树——平衡的二叉搜索树

【多动图警告】本文详细介绍了平衡树,加了一些动图和自己的理解

tunmang5421的博客 1912

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【数据结构】平衡树

平衡树作为数据结构领域的重要成员,以其独特的自平衡特性,为数据的存储、检索和动态更新提供了高效的解决方案。我们深入剖析了常见的平衡树类型,如严格平衡的 AVL 树、近似平衡的红黑树以及结构独特的 2 - 3 树,了解了它们各自的平衡策略、插入删除等操作原理。在实际应用中,平衡树在数据库索引、搜索引擎等关键领域发挥着不可替代的作用,大大提升了系统的性能和效率。然而,平衡树的知识体系远不止于此,它还有许多值得我们深入探索的地方。

大雨淅淅的博客 1409

平衡二叉树(AVL):,“平衡”是指什么?为什么要“平衡”?

也就是说,一棵失衡的树,是有可能有多棵子树同时失衡的。如 LR 型最后的根结点为原来的根的左孩子的右孩子,RL 型最后的根结点为原来的根的右孩子的左孩子。只不过 AVL 树在删除节点后需要重新检查平衡性并修正,同时,删除操作与插入操作后的平衡修正区别在于,插入操作后只需要对插入栈中的弹出的第一个非平衡节点进行修正,而删除操作需要修正栈中的所有非平衡节点。对于删除操作造成的非平衡状态的修正,可以这样理解:对左或者右子树的删除操作相当于对右或者左子树的插入操作,然后再对应上插入的四种情况选择相应的旋转就好了。

zxf347085420的博客 2574

二叉查找树的平衡(DSW)

树适合于表示某些领域的层次结构(比如Linux的文件目录结构),使用树进行查找比使用链表快的多,理想情况下树的查找复杂度O(log(N)),而链表为O(N),但理想情况指的是什么情况呢?一般指树是完全平衡的时候。哪最坏的情况是什么呢?就是树退化为链表的时,这时候查找的复杂度与链表相同。就失去了树结构的意义。所以树的平衡是非常重要的,这一节我们主要讨论树的平衡问题。 如果树中任一节点的两个子树的高...

内核思考 1457

平衡树相关知识及如何判断一棵树是否平衡

文章目录概念代码实现判断一棵二叉树是否为平衡树 概念 平衡树(Balance Tree,BT) 指的是,任意节点的子树的高度差都小于等于1。 常见的符合平衡树的有: B树(多路平衡搜索树) AVL树(二叉平衡搜索树) 红黑树 (自平衡二叉查找树),AVL树的特化 代码实现判断一棵二叉树是否为平衡树 从下到上判断(DFS后序遍历) fun 函数实现后序遍历+剪枝: 返回值: 当前节点 cur 左 / 右子树的深度差 ≤1 时:返回当前子树的深度,即 左 / 右子树的深度最大值 +1( max(

Jormungand_V的博客 1302

树的平衡 AVL Tree

本篇随笔主要从以下三个方面介绍树的平衡: 1):BST不平衡问题 2):BST 旋转 3):AVL Tree 一:BST不平衡问题的解析 之前有提过普通BST的一些一些缺点,例如BST的高度是介于lgN和N之间的,如果是N的的话,显然效率很低,不是我们需要的;但是在实际情况中,BST的高度h = N的情况却经常出现,例如下图所示。在BST中search,insert的runni...

Abcs12345789的博客 387

AVL树平衡旋转详解

感谢大佬!感谢大佬!概述 AVL树又叫做平衡二叉树。前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树)。由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, 2, 3, 4, 5, 6, 7..., n。在BST树中,比较理想的状况是每个子树的左子树和右子树的高度相等,此时搜索的时间复杂度是log(N)。可是,一旦这棵树演化成了线型树的时候,这个理想的情况...

Marcus-Bao的个人主页 5563

数据结构:AVL树的平衡调整——LL,LR,RL,RR

AVL树的全称是平衡搜索二叉树,本质上也是一个二叉搜索树(BST),满足BST树的所有性质。 但是我们在使用二叉搜索树的时候,我们知道通常情况在BST中搜索一个节点的时间复杂度是O(lgn)。 最坏的情况为O(n),这种情况就是出现连续的左子树/右子树,如下图所示: 这种情况其实就已经是链式存储,无法将树的优势体现出来。 为了避免这种情况,我们就要保证这个树随时都是平衡的。当然要求不能...

Eyoru的博客 1万+

平衡二叉树

博客思路 1.通过二叉排序树引出平衡二叉树 2.如何判断是不是一棵平衡二叉树 3.平衡因子 4.左旋  右旋   双旋 5.通过画图创建一棵二叉排序树 6.二叉排序树的代码思路和整体框架   1.二叉排序树 二叉排序树,又叫二叉查找树,它或者是一棵空树;或者是具有以下性质的二叉树: 1. 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 2. 若它的右子树不空,则右...

xiaohui987987的博客 1万+

数据结构_平衡二叉搜索树(AVL树)

平衡二叉搜索树 在二叉搜索树中,已经知道search、insert和remove等主要接口的运行时间均正比于树的高度。但是在最坏的情况下,二叉搜索树可能退化成列表,此时查找的效率会降至O(n)。因此,通常通过控制树高,来控制最坏情况下的时间复杂度。 对于节点数目固定的BST,越是平衡,最坏情况下的查找速度越快,如下图所示: 为了理解平衡二叉树,我们首先要理解几个主要概念,理想平衡与适度平...

xc13212777631的博客 8891

ALV树与树的平衡

ALV树,是指带有平衡条件的二叉查找树。这个平衡条件,就是左子树和右子树的高度差的绝对值小于等于1. 然而,在对ALV树进行插入结点时,就有可能破坏了这种平衡。于是,为了使被破坏平衡的AVL树恢复平衡,就需要对这棵树进行旋转。根据实际,可以分为四种情况: 情况1:在树B的左子树(L)的左子树(L)的位置上插入节点E(即LL) 插入后: 在树B的左子树的左子树的位置上插入节点E后,树A的左子树高度...

David的博客 1455
上一篇: 深入剖析C语言CSV引号嵌套机制(资深工程师20年经验总结)
下一篇: C语言中TCP Keepalive设置全攻略:3步实现稳定长连接
BytePerch
博客等级 码龄1年 164粉丝 1971原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值