数据结构-数型查找

news2024/11/25 15:33:22

二叉排序树(BST)

二叉排序树,又称二叉查找树(BST,Binary Search Tree)
一颗二叉树或者是空二叉树,或者是具有如下性质的二叉树:
左子树上所有结点的关键字均小于根结点的关键字;
右子树上所有结点的关键字均大于根结点的关键字;
左子树和右子树又各是一颗二叉排序树

左子树结点值<根结点值<右子树结点值
进行中序遍历,可以得到一个递增的有序序列
二叉排序树的查找

BSTNode *BST_Search(BSTree T,int key){
	while(T!=NULL&&key!=T->key){	//若树空或等于根结点值,则结束循环
        if(key<T->key) T=T->lchild;	//小于,则在左子树上查找
        else T=T->rchild;		//大于,则在右子树上查找
    }
    return T;
}
//在二叉排序树中查找值为key的结点(递归实现)
BSTNode *BSTSearch(BSTree T,int key){
	if(T==NULL)
        return NULL;//查找失败
    if(key==T->key)
        return T;//查找成功
    else if(key<T->key)
        return BSTSearch(T->lchild,key);//在左子树中找
    else
        return BSTSearch(T->rchild,key);//在右子树中找
}

二叉排序树的插入
若原二叉排序树为空,则直接插入结点;否则,若关键字k小于根结点值,则插入到左子树,若关键字k大于根结点值,则插入到右子树

//在二叉排序树插入关键字为k的新结点(递归实现)
int BST_Insert(BSTree &T,int k){
	if(T==NULL){	//原树为空,新插入的结点为根结点
        T=(BSTree)malloc(sizeof(BSTNode));
        T->key=k;
        T->lchild=T->rchild=NULL;
        retunr 1;	//返回1,插入成功
    }
    else if(k==T->key)	//树中存在相同关键字的结点,插入失败
        return 0;
    else if(k<T->key)	//插入到T的左子树
        return BST_Insert(T->lchild,k);
    else 				//插入到T的右子树
        return BST_Insert(T->rchild,k);
}

二叉排序树的删除
先搜索找到目标结点:
1、若被删除结点z是叶结点,则直接删除,不会破坏二叉排序树的性质。
2、若结点z只有一棵左子树或右子树,则让z的子树成为z父结点的子树,替代z的位置。
3、若结点z有左、右两棵子树,则令z的直接后继(或直接前驱)替代z,然后从二叉排序树中删去这个直接后继(或直接前驱),这样就转换成了第一或第二种情况。
z的后继:z的右子树中最左下结点(该节点一定没有左子树)
z的前驱:z的左子树中最右下结点(该节点一定没有右子树)
查找效率分析
查找长度–在查找运算中,需要对比关键字的次数称为查找长度,反映了查找操作时间复杂度
image.png
image.png

平衡二叉树

平衡二叉树(Balanced Binary Tree),简称平衡树(AVL树)–树上任一结点的左子树和右子树的高度之差不超过1。
结点的平衡因子=左子树高-右子树高
平衡二叉树的插入
每次调整的对象都是“最小不平衡子树”
调制最小不平衡子树
LL在A的左孩子的左子树中插入导致不平衡
RR在A的右孩子的右子树中插入导致不平衡
LR在A的左孩子的右子树中插入导致不平衡
RL在A的右孩子的左子树中插入导致不平衡
调整最小不平衡子树(LL)
image.png

  1. LL平衡旋转(右单旋转)。由于在结点A的左孩子(L)的左子树(L)上插入了新结点,A的平衡因子由1增至2,导致以A为根的子树失去平衡,需要一次向右的旋转操作。将A的左孩子B向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。
    调整最小不平衡子树(RR)
    image.png
    2)RR平衡旋转(左单旋转)。由于在结点A的右孩子®的右子树®上插入了新结点,A的平衡因子由-1减至-2,导致以A为根的子树失去平衡,需要一次向左的旋转操作。将A的右孩子B向左上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则作为A结点的右子树
    代码思路
    image.png
    实现f向右下旋转,p向右上旋转:
    其中f是爹,p为左孩子,gf为f他爹
    1:f->lchild=p->rchild;
    2:p->rchild=f;
    3:gf->lchild/rchild=p;
    image.png
    实现f向左下旋转,p向左上旋转:
    其中f是爹,p为右孩子,gf为f他爹
    1:f->rchild=p->lchild;
    2:p->lchild=f;
    3:gf->lchild/rchild=p;
    调整最小不平衡子树(LR)
    image.png
    3)LR平衡旋转(先左后右双旋转)。由于在A的左孩子(L)的右子树®上插入新结点,A的平衡因子由1增至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先左旋转后右旋转。先将A结点的左孩子B的右子树的根结点c向左上旋转提升到B结点的位置,然后再把该c结点向右上旋转提升到A结点的位置
    image.png
    调整最小不平衡子树(RL)
    image.png
    4)RL平衡旋转(先右后左双旋转)。由于在A的右孩子(R)的左子树(L)上插入新结点,A的平衡因子由-1减至-2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先右旋转后左旋转。先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把该C结点向左上旋转提升到A结点的位置
    image.png
    image.png

image.png
查找效率分析
若树高为h,则最坏情况下,查找一个关键字最多需要对比h次,即查找操作的时间复杂度不可能超过O(h)
image.png

红黑树

为什么发明红黑树?
平衡二叉树AVL:插入\删除 很容易破坏“平衡”特性,需要频繁调整树的形态。如:插入操作导致不平衡,则需要先计算平衡因子,找到最小不平衡子数(时间开销大),再进行LL\RR\LR\RL调整
红黑树:插入\删除 很多时候不会破坏“红黑”特性,无需频繁调整树的形态。即使需要调整,一般都可以在常数级时间内完成

平衡二叉树:适用于以查为主、很少插入\删除的场景
红黑树:适用于频繁插入、删除的场景,实用性更强

红黑树的定义

红黑树是二叉排序树->左子树结点值<=根结点值<=右子树结点值
与普通BST相比:
1、每个结点或是红色,或是黑色的
2、根节点是黑色的
3、叶结点(外部结点、NULL结点、失败结点)均是黑色的
4、不存在两个相邻的红结点(即红结点的父节点和孩子结点均是黑色)
5、对每个结点,从该节点到任一叶结点的简单路径上,所含黑结点的数目相同

struct RBnode{		//红黑树的结点定义
	int key;		//关键字的值
    RBnode* parent;	//父节点指针
    RBnode* lChild;	//左孩子指针
    RBnode* rChild;	//右孩子指针
    int color;		//结点颜色,如:0/1 表示 黑/红
}

结点的“黑高”
从某结点出发(不含该结点)达到任一空叶结点的路径上黑结点总数
image.png
红黑树性质
1、从根节点到叶结点的最长路径不大于最短路径的2倍
2、有n个内部节点的红黑树高度h<=2log(n+1)
红黑树的查找
image.png

红黑树的插入

从一颗空的红黑树开始,插入:20,10,5,30,40,57,3,2,4,35,25,18,22,23,24,19,18
先查找,确定插入位置(原理同二叉排序树),插入新结点
新结点是根–染为黑色
新结点非根–染为红色

  • 若插入新结点后依然满足红黑树定义,则插入结束
  • 若插入新结点后不满足红黑树定义,需要调整,使其重新满足红黑树定义(看新结点叔叔的颜色)
    • 黑叔:旋转+染色
      • LL型:右单旋,父换爷+染色
      • RR型:左单旋,父换爷+染色
      • LR型:左、右双旋,儿换爷+染色
      • RL型:右、左双旋,儿换爷+染色
    • 红叔:染色+变新
      • 叔父爷染色,爷变为新结点

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

image.png
image.png
image.png

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

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

相关文章

LeetCode(9)跳跃游戏【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 55. 跳跃游戏 1.题目 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回…

在Linux系统下微调Llama2(MetaAI)大模型教程—Qlora

Llama2是Meta最新开源的语言大模型&#xff0c;训练数据集2万亿token&#xff0c;上下文长度是由Llama的2048扩展到4096&#xff0c;可以理解和生成更长的文本&#xff0c;包括7B、13B和70B三个模型&#xff0c;在各种基准集的测试上表现突出&#xff0c;最重要的是&#xff0c…

《QT从基础到进阶·二十二》QGraphicsView显示大量图形项item导致界面卡顿的解决办法

有时候因业务需要&#xff0c;paint函数在界面上绘制了成百上千个图形项Items&#xff0c;导致操作界面的时候有明显的卡顿感&#xff0c;下文会提供一种比较好的解决办法&#xff0c;先来了解下QGraphicsItem的缓存方式。 &#xff08;1&#xff09;setCacheMode(QGraphicsIt…

0基础学习PyFlink——水位线(watermark)触发计算

在《0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)》和《0基础学习PyFlink——个数滑动窗口&#xff08;Sliding Count Windows&#xff09;》中&#xff0c;我们发现如果窗口中元素个数没有把窗口填满&#xff0c;则不会触发计算。 为了解决长期不计算的问题&a…

日志及其框架

日志技术的概述 日志 生活中的日志&#xff1a; 生活中的日志就好比日记&#xff0c;可以记录你生活的点点滴滴。 程序中的日志&#xff1a; 程序中的日志可以用来记录程序运行过程中的信息&#xff0c;并可以进行永久存储。 以前记录日志的方式&#xff08;输出语句&#…

设置专属链接的这些作用你知道吗?

专属链接作为一种个性化的链接&#xff0c;用于为特定的客户或群体提供定制化的体验或服务。对于企业来说&#xff0c;每个渠道或者每个客户都能拥有一个专属链接是无比便利的事情。企业可以将这个链接嵌入到各种宣传物料中&#xff0c;让客户通过输入链接即可进入与客服的交流…

thinkphp5 连接多个服务器数据库

如果你的database.php 是这样&#xff0c; 这是默认的db连接配置 如果还想连接其他服务器&#xff0c;或数据库 在config.php中追加数据库配置&#xff0c; 在使用的地方调用&#xff1a; use think\Db;public function test(){$db3Db::connect(config(db3));$result $db3…

使用Python的requests库模拟爬取地图商铺信息

目录 引言 一、了解目标网站 二、安装requests库 三、发送GET请求 四、解析响应内容 五、处理异常和数据清洗 六、数据存储和分析 七、数据分析和可视化 八、注意事项和最佳实践 总结 引言 随着互联网的快速发展&#xff0c;网络爬虫技术已经成为获取数据的重要手段…

Leetcode-104 二叉树的最大深度

递归实现 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

谈谈steam游戏搬砖的收益与风险,以及注意事项

11月CSGO市场行情分析&#xff0c;是否到了该抄底的时候了&#xff1f; 今天&#xff0c;要跟大家分享的Steam平台——全球最大的游戏平台&#xff0c;现在给大家介绍下steam搬砖项目&#xff0c;这个项目既小众又稳定。 先了解一下 steam这个平台是做什么的&#xff0c;steam…

navicat创建MySql定时任务

navicat创建MySql定时任务 前提 需要root用户权限 需要开启定时任务 1、开启定时任务 1.1 查看定时任务是否开启 mysql> show variables like event_scheduler;1.2 临时开启定时任务(下次重启后失效) set global event_scheduler on;1.3 设置永久开启定时任务 查看my…

c语言-数据结构-带头双向循环链表

目录 1、双向循环链表的结构 2、双向循环链表的结构体创建 3、双向循环链表的初始化 3.1 双向链表的打印 4、双向循环链表的头插 5、双向循环链表的尾插 6、双向循环链表的删除 6.1 尾删 6.2 头删 6.3 小节结论 7、查找 8、在pos位置前插入数据 9、删除pos位…

Scala---介绍及安装使用

一、Scala介绍 1. 为什么学习Scala语言 Scala是基于JVM的语言&#xff0c;与java语言类似&#xff0c;Java语言是基于JVM的面向对象的语言。Scala也是基于JVM&#xff0c;同时支持面向对象和面向函数的编程语言。这里学习Scala语言的原因是后期我们会学习一个优秀的计算框架S…

单链表(7)

插入函数——插入数据&#xff0c;在链表plist的pos位置插入val数据元素 由图知&#xff0c;poslength时&#xff0c;是可以插入的 在大多数情况下&#xff0c;说位置的时候&#xff0c;从0开始计数&#xff1b;说第几个数据的时候&#xff0c;从1开始计数 现在来测试一下 这就…

CSDN的规范、检测文章质量、博客等级好处等等(我也是意外发现的,我相信很多人还不知道,使用分享给大家!)

前言 都是整理官方的文档&#xff0c;方便自己查看和检查使用&#xff0c;以前我也不知道。后来巧合下发现的&#xff0c;所以分享给大家&#xff01; 下面都有官方的链接&#xff0c;详情去看官方的文档。 大家严格按照官方的规范去记录自己工作生活中的文章&#xff0c;很快…

MacOS Ventura 13 优化配置(ARM架构新手向导)

一、系统配置 1、About My MacBook Pro 2、在当前标签打开新窗口 桌面上创建目录的文件夹&#xff0c;每次新打开一个目录&#xff0c;就会创建一个窗口&#xff0c;这就造成窗口太多&#xff0c;不太好查看和管理&#xff0c;我们可以改成在新标签处打开新目录。需要在&…

电动自动换刀高速电主轴的技术优势浅析

在制造业中&#xff0c;自动化技术的发展一直是一个重要的话题。其中&#xff0c;电动自动换刀被认为是一项高效、智能、先进的技术&#xff0c;在高速电主轴中使用电动自动换刀这一技术&#xff0c;不仅能够缩短换刀时间&#xff0c;还能减少换刀失误&#xff0c;本文将探讨Sy…

光计算1周2篇Nature,英伟达的时代彻底结束!

近期&#xff0c;光计算领域连续发出重量级文章&#xff0c;刊登在学术界的顶级期刊上。一时间&#xff0c;各大媒体纷纷转发&#xff0c;读者们也纷纷感叹&#xff1a;中国芯片取代英伟达的机会来了&#xff01;今天&#xff0c;光子盒用这篇万字长文为大家梳理光计算的背景、…

指标类型(一):北极星指标、虚荣指标

每个产品都有很多指标&#xff0c;每个指标都反映了对应业务的经营情况。但是在实际业务经营中&#xff0c;却要求我们在不同的产品阶段寻找到合适的指标&#xff0c;让这个指标可以代表当前产品阶段的方向和目标&#xff0c;让这个指标不仅对业务经营团队&#xff0c;而且对产…

双十一网络电视盒子哪个品牌好?内行分享权威电视盒子排行榜

双十一大促正如火如荼进行中&#xff0c;因为我从事的工作和电视盒子有关&#xff0c;身边的朋友们在选购电视盒子时不知道从何下手就会问我的意见&#xff0c;本期将盘点业内公认的电视盒子排行榜&#xff0c;给双十一想买电视盒子的朋友们做个参考。 排行一&#xff1a;泰捷W…