数据结构入门学习(全是干货)——树(中)

news2024/9/21 14:18:38

数据结构入门学习(全是干货)——树(中)

1 二叉搜索树(Binary Search Tree,简称 BST)

1.1 二叉搜索树及查找

二叉搜索树(Binary Search Tree, BST) 是一种特殊的二叉树,它满足以下性质:

  • 对于每一个节点,其左子树上所有节点的值都小于该节点的值。
  • 右子树上所有节点的值都大于该节点的值。
  • 每棵子树也是一棵二叉搜索树。

二叉搜索树的基本操作:
  1. 查找元素(Find)

    查找从根结点开始,如果树为空,返回NULL
    
    若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
    	1.若X小于根结点赋值,只需在左子树中继续搜索;
    	2.如果X大于根结点的键值,在右子树中进行继续搜索;
    	3.若两者比较结果是相等,搜索完成,返回指向此结点的指针
    
    Position Find(ElementType X,BinTree BST)
    {
    	if(!BST) return NULL;//查找失败
        if( X > BST -> Data)//这是尾递归,下面的两个Find的也是同理
            return Find(X,BST->Right);//在右子树中继续查找
        Else if(X < BST -> Data)
            return Find(X,BST->Left);//在左子树中继续查找
        else//X == BST->Data
            return BST;//查找成功,返回结点的找到结点的地址
    }
    
    
    //由于非递归函数的执行效率高,可将"尾递归"函数改为迭代函数
    Position IterFind(ElementType X,BinTree BST)
    {
    	while(BST){
            if(X > BST->Data)
                BST = BST -> Right;//向右子树中移动,继续查找
            else if(X < BST->Data)
                BST = BST ->Left;//向左子树中移动,继续查找
            else//X == BST ->Data
                return BST;//查找成功,返回结点的找到结点的地址
        }
            return NULL;//查找失败
    }
    
    //查找的效率决定于树的高度
    
  2. 插入元素

  3. 删除元素

查找最大和最小元素
  • 查找最小元素:从根节点开始,沿左子树一直往下找到最左端的叶子节点。
  • 查找最大元素:从根节点开始,沿右子树一直往下找到最右端的叶子节点。
查找最小元素的递归函数示例:
Node* findMin(Node* root) {
    if (root == nullptr || root->left == nullptr)
        return root;
    return findMin(root->left);
}
查找最大元素的迭代函数示例:
Node* findMax(Node* root) {
    while (root->right != nullptr)
        root = root->right;
    return root;
}

1.2 二叉搜索树的插入

插入操作的关键是要找到元素应该插入的位置,这与查找操作类似。插入时,我们从根节点开始,与节点的值进行比较:

  • 如果插入的值小于当前节点的值,则递归到左子树。
  • 如果插入的值大于当前节点的值,则递归到右子树。
  • 如果找到了空节点,则插入该元素。
插入元素的算法:

BinTree Insert(ElementType X,BinTree BST)
{
	if(!BST){
        //若原树为空,生成并返回一个结点的二叉搜索树
        BST = malloc(sizeof(struct TreeNode));
        BST -> Data = X;
        BST -> Left = BST -> Right = NULL;
    }else //开始找要插入元素的位置
        if(X < BST->Data )
            BST -> Left = Insert(X,BST->Left);//递归插入左子树
    else if(X > BST->Data)
        BST->Right = Insert(X,BST->Right);//递归插入右子树
    //else X已经存在,什么都不做
    return BST;
}

1.3 二叉搜索树的删除

删除一个节点需要考虑三种情况:

  1. 删除的是叶结点:直接删除,并修改其父节点的指针为 NULL

  2. 删除的节点只有一个子节点:

    • 将其父节点的指针指向要删除节点的唯一孩子。

  3. 删除的节点有两个子节点:

    • 用右子树的最小元素或左子树的最大元素替代被删除的节点,然后删除这个替代节点。

删除元素的代码实现:
BinTree Delete (ElementType X,BinTree BST)
{
	Position Tmp;   
    if(!BST) printf("要删除的元素未找到");
    else if(X < BST ->Data)
        BST->Left = Delete(X,BST->Left);//左子树递归删除,返回左子树删除了x这个结点之后,新的左子树根结点的地址
    else if(X > BST->Data)
        BST->Right = Delete( X,BST->Right);//右子树递归删除
    else//找到要删除的结点
        if(BST->Left && BST->Right ){//被删除结点有左右两个子节点
            Tmp = FindMin(BST->Right);//在右子树中找最小的元素填充删除结点
            BST->Data = Tmp->Data;
            BST->Right = Delete(BST->Data,BST->Right);//在删除结点的右子树中删除最小元素
        }else{//被删除结点有一个或无子结点
            Tmp = BST;
            if(!BST->Left)//有右孩子或无子结点
                BST = BST->Right;
            else if(!BST->Left)//有左孩子或无子结点
            	BST = BST->Left;
            free(Tmp);
        }
}
return BST;

2 平衡二叉树(Balanced Binary Tree)

2.1 什么是平衡二叉树

平衡二叉树是一种特殊的二叉树,其左子树和右子树的高度差不超过1(即左右子树的高度差最多为1)。如果一棵树的每个子树也都满足这个条件,则该树为平衡二叉树。

平衡因子:

平衡因子是某个节点左右子树的高度差。平衡因子计算公式:


平衡因子 = 左子树高度 - 右子树高度

对于平衡二叉树,所有节点的平衡因子绝对值都小于或等于1。

举例:

至少需要 7 个结点才能构造出一棵高度为 3 的平衡二叉树。


2.2 平衡二叉树的调整

在二叉搜索树的插入或删除操作中,如果树的平衡被打破,就需要进行调整,使其重新成为平衡二叉树。调整的方法是旋转,常见的四种旋转操作有:

1. RR旋转(右右旋转)

当插入点位于节点的右子树的右子树时,执行RR旋转。通过一次左旋,使树重新平衡。

2. LL旋转(左左旋转)

当插入点位于节点的左子树的左子树时,执行LL旋转。通过一次右旋,使树重新平衡。

3. LR旋转(左右旋转)

当插入点位于节点的左子树的右子树时,执行LR旋转。首先对左子树进行RR旋转,然后对整个树进行LL旋转。

4. RL旋转(右左旋转)

当插入点位于节点的右子树的左子树时,执行RL旋转。首先对右子树进行LL旋转,然后对整个树进行RR旋转。


3 链表逆转

3.1 链表基本概念

链表是一种线性数据结构,每个节点包含两部分:

  1. 数据域:存储数据。
  2. 指针域:存储指向下一个节点的指针。

3.2 单链表逆转算法

链表逆转的核心思想是逐个反转节点的指针方向,以下是链表逆转的伪代码实现:

Ptr Reverse(Ptr head) {
    Ptr newHead = nullptr;
    Ptr oldHead = head;
    while (oldHead != nullptr) {
        Ptr temp = oldHead->next;
        oldHead->next = newHead;
        newHead = oldHead;
        oldHead = temp;
    }
    return newHead;
}

边界测试:

  1. 链表长度为 0 或 1 的情况。
  2. 链表长度恰好为反转单位长度的整数倍。
  3. 逆转链表的其他边界情况。

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

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

相关文章

四、JVM原理-4.1、JVM介绍

4.1、JVM介绍 4.1.1、如何理解Java虚拟机&#xff0c;它的结构是如何设计的&#xff1f; 答&#xff1a; Java虚拟机&#xff08;Java Virtual Machine&#xff0c;JVM&#xff09;是Java语言编写的程序在运行时的执行环境。它是Java的核心组成部分&#xff0c;负责解释和执行…

开源项目 face parsing 人脸区域分割 人像区域分割 人脸分割 人像区域分割 BiSeNet

开源项目 - face parsing 人脸区域分割 人像区域分割 人脸分割 人像区域分割 BiSeNet 人像分割 开源项目地址&#xff1a;https://gitcode.net/EricLee/faceparsing 包括开源数据集 和 预训练模型 咨询合作 DataBall 项目&#xff0c;欢迎加以下微信。 助力快速掌握数据集的信…

HarmonyOS 速记

目录 装饰器Entry(入口)Component(组件)State(状态)Prop(属性)Preview(预览)PreviewerInspector 结构体structbuild自定义组件自定义 Custom 组件 容器Row(行) & Column(列)RelativeContainer(相对布局容器)marginpaddingSwiper(轮播图)Grid(网格容器)List(列表) 组件Image…

python函数一:函数的概念、函数定义与调用、函数的参数、函数的返回值、说明文档以及函数的嵌套调用

文章目录 1. 函数介绍1.1 函数的概念1.2 函数定义与调用1.2 函数的参数1.3 函数的返回值1.4 说明文档 2. 函数的嵌套调用2.1 嵌套调用及执行流程2.2 嵌套调用的应用 1. 函数介绍 1.1 函数的概念 什么是函数&#xff1f; 函数:是一个被命名的、独立的、完成特定功能的代码段&am…

使用c#制作一个小型桌面程序

封装dll 首先使用visual stdio 创建Dll新项目,然后属性管理器导入自己的工程属性表&#xff08;如果没有可以参考visual stdio 如何配置opencv等其他环境&#xff09; 创建完成后 系统会自动生成一些文件&#xff0c;其中 pch.cpp 先不要修改&#xff0c;pch.h中先导入自己需…

Python画笔案例-053 绘制海龟螺旋图

1、绘制海龟螺旋图 通过 python 的turtle 库绘制 海龟螺旋图&#xff0c;如下图&#xff1a; 2、实现代码 绘制海龟螺旋图&#xff0c;以下为实现代码&#xff1a; """海龟螺旋图.py""" import turtle from random import randintscreen turtl…

引入第三方字体图标icon

引入第三方字体图标icon 1.登录阿里巴巴icon库 2.点开ui提供的字体图标并下载 3.解压download 将font_4008950_i6fkbudh8ld文件放置项目中例如&#xff1a;放在assets文件夹下 4.然后再main.js中引入 import ‘/assets/font_4008950_i6fkbudh8ld/iconfont.css’; 5.项目中应…

Rsync未授权访问漏洞复现及彻底修复

一、什么是 Rsync&#xff1f; Rsync 是一种广泛使用的文件传输工具&#xff0c;它允许系统管理员和用户通过局域网&#xff08;LAN&#xff09;或广域网&#xff08;WAN&#xff09;在计算机之间同步文件和目录。Rsync 支持通过本地或远程 shell 访问&#xff0c;也可以作为守…

STM32——输入捕获

输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器&#xff0c;除了TIM6、TIM7&#xff0c;其他的定时器都有输入捕获的功能。应用场景是编码器。 测量频率 当捕获通道TIx 上出现上升沿时&#xff0c;发生第一次捕获&#xff0c;计数器CNT 的值会被锁存到捕获寄存…

Java中的红黑树(如果想知道Java中有关红黑树的知识点,那么只看这一篇就足够了!)

前言&#xff1a;红黑树作为一种自平衡的二叉搜索树&#xff0c;在计算机科学领域具有极其重要的地位。它通过颜色约束和旋转操作保持树的高度平衡&#xff0c;从而保证了查找、插入、删除等操作的高效性。红黑树广泛应用于操作系统的调度算法、数据库索引、Java集合框架等领域…

「全球大模型竞技场」更新:DeepSeek-V2.5全面领跑国内模型

原文&#xff1a;深度求索 DeepSeek 月初&#xff0c;我们发布并开源了 DeepSeek-V2.5&#xff0c;一个融合通用与代码能力的全新模型。 近日&#xff0c;LMSYS 组织的全球大模型竞技场&#xff08;ChatBotArena&#xff09;更新结果发布&#xff0c;DeepSeek-V2.5 排名位列国…

额定剩余动作电流继电器有什么功能?

ASJ系列剩余电流动作继电器可与低压断路器或低压接触器等组装成组合式的剩余电流动作保护器&#xff0c;为现代电力系统设计&#xff0c;旨在提高电力系统的安全性和可靠性。其技术和多功能特性使其成为电力管理和监测的理想选择。主要适用于交流50Hz&#xff0c;额定电压为400…

iPhone 16系列:熟悉的味道,全新的体验

来看看iPhone 16和Plus这两个新成员&#xff0c;实话说&#xff0c;它们和之前曝光的样子几乎完全一致。下面我们就一起来细数一下这次的几大变化吧。 外观设计&#xff1a;焕然一新 首先&#xff0c;最显眼的变化就是后置镜头模组的布局调整为了垂直排列。这一改变使得整个背…

29912分页

拆分地址&#xff1a; 003FDFB0 0000 0000 0011 1111 1101 1111 1011 000000 0*8 00 0000 001 -> 1*8 1 1111 1101 -> 1FD*8 1111 1011 0000 -> FB0PROCESS 883ef7c8 SessionId: 1 Cid: 09b0 Peb: 7ffdf000 ParentCid: 0588DirBase: bf2484a0 ObjectTable: 98…

将多个pdf合并成一个文件?这几种合并方法很好用!

如何将多个pdf合并成一个文件&#xff1f;面对日益增长的PDF文档&#xff0c;我们时常陷入管理困境&#xff0c;这不仅仅关乎于时间与精力的巨大消耗&#xff0c;因为这些孤立的PDF文件如同散落的拼图碎片&#xff0c;让关键信息的搜寻变得如同大海捞针&#xff0c;严重拖慢了工…

双指针算法:快速解决问题的小技巧(Java代码实现)

“人的一生是短暂的&#xff0c;但如果卑鄙地过这短暂的一生&#xff0c;那就太长了。” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;双指针简介对撞指针快慢指针例题聪明的小羊肖恩神奇的数组盛最多的水 总结 前言 写在开始&#xff1a; 双指针算法是一种经典且高效…

“中秋快乐”文字横幅的MATLAB代码生成

中秋快乐呀朋友们&#xff01;&#xff01;&#xff01; 给大家带来一个好玩的代码&#xff0c;能够生成“中秋快乐”的横幅文字&#xff0c;比较简单&#xff0c;当然你也可以根据自己的需求去更改文字和背景&#xff0c;废话不多说&#xff0c;直接展示。 文字会一直闪烁&…

智能BI项目第三期

AIGC AI 提问技巧 为了让 Al 更好地理解我们的输入&#xff0c;并给出预期精确的输出&#xff0c;需要严格控制我们的提问词。 1.使用系统预设 控制输入格式(便于Al精确地理解我们的需求) 你是一个数据分析师和前端开发专家&#xff0c;接下来我会按照以下固定格式给你提供…

《深度学习》PyTorch框架 优化器、激活函数讲解

目录 一、深度学习核心框架的选择 1、TensorFlow 1&#xff09;概念 2&#xff09;优缺点 2、PyTorch 1&#xff09;概念 2&#xff09;优缺点 3、Keras 1&#xff09;概念 2&#xff09;优缺点 4、Caffe 1&#xff09;概念 2&#xff09;优缺点 二、pytorch安装 1、安装 2、…

传输层协议 —— UDP协议

目录 0.前言 1.UDP协议格式 16位源端口和目的端口 16位UDP长度 16位校验和 2.UDP协议特点 无连接 不可靠 面向数据报 3.UDP的缓冲区 0.前言 首先&#xff0c;我们得明确一点&#xff0c;网络模型是分层的。自底向上分别是物理层、数据链路层、网络层、传输层、应用层…