数据结构-二叉查找树(BST)

news2024/11/22 20:42:26

二叉查找树

在这里插入图片描述

需要满足这些规则:

  • 左子节点小于父节点
  • 右子节点大于父节点

查找的效率

非常好,每次都能根据大小去舍弃另一半的分支,极大的减少的比对次数

具体的性能,取决于树的层数和平衡程度。
在这里插入图片描述

BST树的节点

struct Node
{
	Node* parent;
	Node* left;
	Node* right;
	int val;
}

BST的插入

bool Insert(Node* root,Node* newNode)
{
	Node* head =nullptr;
	if(root==nullptr)
	{
		*root = *newNode;
		return true;
	}
	
	Node* current = root;
	while(current!=nullptr)
	{
		if(newNode->val==current->val) return nullptr;
		else if(newNode->val>current->val) 
		{
			if(current->right==nullptr)
			{
				current->right = newNode;
				newNode->parent = current;
			}
			current = current->right;
		}
		else if(newNode->val<current->val)
		{
			if(current->left==nullptr)
			{
				current->left = newNode;
				newNode->parent = current;
			}
			current = current->left;
		}
	}
	return head;
}

BST查找

Node* Search(Node* root, int target)
{
    Node* current = root;
    while (current != nullptr)
    {
        if (target == current->val)
        {
            return current; // 找到目标节点,返回它
        }
        else if (target < current->val)
        {
            current = current->left; // 目标值较小,向左子树查找
        }
        else
        {
            current = current->right; // 目标值较大,向右子树查找
        }
    }
    return nullptr; // 未找到目标节点
}

BST删除

BST的删除比较复杂,需要先了解二叉树的遍历顺序
《二叉树》

在这里插入图片描述
二叉树的前驱和后继是按中序遍历计算的,L称为前驱,R为后继。
在这里插入图片描述

  1. 如果一个树没有子节点,直接删除
  2. 如果一个树只有一个子节点,删除当前节点并把子节点补到这个位置
  3. 如果有两个子节点 ,操作复杂,进行以下操作
    • 找到被删除的节点的左子树最大值或右子树最小值
    • 我们选中右最小或者选中左最大
    • 我们将这个选中的节点的子树连接在选中的节点的父节点
    • 将选中节点替换到删除节点,并持有被删除节点的左右子树
//查找子树最大值
Node* FindMax(Node* node)
{
	Node* current = node;
	while(current!=nullptr)
	{
		current = current->right;
	}
	return current;
}
Node* FindMin(Node* node)
{
	Node* current = node;
	while(current!=nullptr)
	{
		current = current->left;
	}
	return current;
}

//需要先搜索找出被删除节点的指针
Node* DeleteNode(Node* root,Node* target)
{
	//删除根节点,返回空指针
	if(root==target)
	{
		return nullptr;
	}
	//子节点不存在,将当前节点从父节点上移除
	if(target->left==nullptr&&target->right==nullptr)
	{
		target->parent = nullptr;
	}
	//一个子节点为空,左子节点为空
	else if(target->left==nullptr)
	{
		if(target==target->parent->left)
		{
			target->parent->left = target->right;
			target->right->parent = target->parent; 
		}
		else
		{
			target->parent->right = target->right;
			target->right->parent = target->parent;
		}
	}
	else if(target->right==nullptr)
	{
		if(target==target->parent->right)
		{
			target->parent->right = target->left;
			target->left->parent = target->parent;
		}
		else
		{
			target->parent->left = target->left;
			target->left->parent = target->parent;
		}
	}
	//两个子节点存在
	else
	{
		//左侧最大,右侧最小值
		Node* min = FindMin(target->right);
		//选中的节点的子树连接在选中的节点的父节点
		min->parent->left = min->left;
		min->left->parent = min->parent;
		min->parent->right= min->right;
		min->right->parent = min->parent;
		//选中节点置换删除节点
		if(target->parent->left==target) 
		{
			target->parent->left=min;
			min->parent = target->parent;
		}
		else 
		{
			target->parent->right = min;
			min->parent = target->parent;
		}
		//选中节点继承被删除节点的子树
		min->left = target->left;
		target->left->parent = min;
		min->right = target->right;
		target->right->parent = min;
		
	}
	
}

子树和相同树

递归实现的,可能存在爆栈风险,但是一般来讲BST的平均深度不会引起这种问题,可以使用。这里不再给出非递归实现

bool isSubtree(TreeNode* s, TreeNode* t) {
    if (!s) return false; // 父树为空,不可能有子树
    if (isSameTree(s, t)) return true; // 当前子树和子树t相同
    return isSubtree(s->left, t) || isSubtree(s->right, t); // 继续递归检查左右子树
}

bool isSameTree(TreeNode* p, TreeNode* q) {
    if (!p && !q) return true; // 两棵树都为空
    if (!p || !q) return false; // 一棵树为空,另一棵不为空
    return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

BST存在一个非常严重的问题,就是可能出现极端情况,这时BST会退化为一个双链表,导致丧失查找优势。
在这里插入图片描述

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

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

相关文章

HTML5+CSSday4综合案例二——banner效果

bannerCSS展示图&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wi…

Unity实现设计模式——策略模式

Unity实现设计模式——策略模式 策略模式是一种定义一些列算法的方法&#xff0c;这些所有的算法都是完成相同的工作&#xff0c;只是实现不同。它可以通过相同的方式调用所有的算法&#xff0c;减少各种算法类与使用算法类之间的耦合。 策略模式的 Strategy 类层次为 Contex…

微信黑名单在哪里找出来?掌握4个步骤即可!

微信的黑名单功能可以帮助用户过滤掉一些不友好的联系人&#xff0c;从而在一定程度上限制与这些联系人的互动。在使用微信的过程中&#xff0c;如果不想被一些陌生人或者恶意用户骚扰&#xff0c;那么可以通过将这些人拉入黑名单来阻断联系。 但是如果是和熟人吵架&#xff0…

SpringBoot 如何使用 Micrometer 进行度量和监控

使用Micrometer进行度量和监控Spring Boot应用程序 在构建和维护现代应用程序时&#xff0c;度量和监控是至关重要的&#xff0c;它们可以帮助您了解应用程序的性能、稳定性和可用性。Spring Boot提供了集成Micrometer的功能&#xff0c;使得度量和监控变得非常容易。本文将介…

设计模式 - 访问者模式

目录 一. 前言 二. 实现 三. 优缺点 一. 前言 访问者模式&#xff0c;即在不改变聚合对象内元素的前提下&#xff0c;为聚合对象内每个元素提供多种访问方式&#xff0c;即聚合对象内的每个元素都有多个访问者对象。访问者模式主要解决稳定的数据结构和易变元素的操作之间的…

DCE/RPC协议详解之-数据包请求响应过程

在windows的域环境中有非常多的协议和服务是基于DCE/RPC协议进行实现的,例如NETLOGON,LSA,SAMR,DSSETUP等。因此在 windows的环境下会大量的遇到DCE/RPC协议,因此有必要对该协议有一个初步的了解,这样的话在遇到对应的数据包,则能够比较清楚的还原数据包中发生了什么。本…

长沙旅行见闻实用帖

最近趁着假期&#xff0c;来了趟长沙游&#xff0c;还是有很多值得记录下来的。 众所周知&#xff0c;长沙市是湖南省的省会城市&#xff0c;也是国务院批复确定的长江中游地区重要的中心城市和长株潭城市群中心城市。它位于湖南省中部偏东&#xff0c;湘江下游&#xff0c;辖6…

常见弯道输送机有哪些

提到弯道输送机您可能首先想到的就是弯道滚筒线&#xff0c;其实除了滚筒线之外&#xff0c;也有一些其他线体可以做弯道&#xff0c;下面就为您总结了4种常见的弯道输送机。 1、弯道皮带线&#xff1a;即线体转弯处设计成皮带输送机&#xff0c;这种形式的转弯设计可以实现不同…

Xcode 15 编译出错问题解决

正常升级xcode 15以后发现原来没有出现报错的代码&#xff0c;现在出现了编译错误。&#xff08;如果没有出现请忽略&#xff09;下面教你如何解决这个问题。 1、pod update更新cocoapods&#xff0c;因为其根据xcode15做了很多的更新&#xff0c;保证cocoapods是最新的。 千…

深入理解PKI

安全始终是网络通信的核心议题&#xff0c;PKI提供了一组标准的网络安全组件&#xff0c;可以为通信双方提供加密、完整性保护、认证等安全基础设施。原文: Public Key Infrastructure (PKI) Jacek DylagUnsplash 由于用户名和密码不足以验证用户的身份&#xff0c;因此PKI(公钥…

数据结构 | (二) List

什么是 List 在集合框架中&#xff0c; List 是一个接口&#xff0c;继承自 Collection 。 Collection 也是一个接口 &#xff0c;该接口中规范了后序容器中常用的一些方法&#xff0c;具体如下所示&#xff1a; Iterable 也是一个接口&#xff0c;表示实现该接口的类是可以逐个…

iPhone15手机拓展坞方案,支持手机快充+传输数据功能

手机拓展坞的组合有何意义&#xff1f;首先是数据存储场景&#xff0c;借助拓展坞扩展出的接口&#xff0c;可以连接U盘、移动硬盘等采用USB接口的设备&#xff0c;实现大文件的快速存储或者流转&#xff1b;其次是图片、视频的读取场景&#xff0c;想要读取相机、无人机SD/TF存…

阿里云ESS弹性伸缩的实例配置以及伸缩组规则配置

文章目录 1.配置伸缩组的实例来源信息1.1.创建伸缩组实例来源配置属性1.2.查看创建的伸缩来源配置信息 2.配置伸缩组的触发规则2.1.创建伸缩规则2.2.创建扩展实例的伸缩规则2.3.创建缩减实例的伸缩规则2.4.扩展缩减规则添加完成 1.配置伸缩组的实例来源信息 伸缩组的属性已经配…

自监督DINO论文笔记

论文名称&#xff1a;Emerging Properties in Self-Supervised Vision Transformers 发表时间&#xff1a;CVPR2021 作者及组织&#xff1a; Facebook AI Research GitHub&#xff1a;https://github.com/facebookresearch/dino/tree/main 问题与贡献 作者认为self-supervise…

【计算机网络黑皮书】传输层

【事先声明】 这是对于中科大的计算机网络的网课的学习笔记&#xff0c;感谢郑烇老师的无偿分享 书籍是《计算机网络&#xff08;自顶向下方法 第6版&#xff09;》 需要的可以私信我&#xff0c;无偿分享&#xff0c;课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…

非局部均值滤波的指令集优化和加速(针对5*5的搜索特例,可达到单核1080P灰度图 28ms/帧的速度)。

非局部均值滤波(Non Local Means&#xff09;作为三大最常提起来的去燥和滤波算法之一&#xff08;双边滤波、非局部均值、BM3D&#xff09;&#xff0c;也是有着很多的论文作为研究和比较的对象&#xff0c;但是也是有着致命的缺点&#xff0c;速度慢&#xff0c;严重的影响了…

【Spring】Spring MVC 程序开发

Spring MVC 程序开发 一. 什么是 Spring MVC1. MVC2. Spring、Spring Boot 与 Spring MVC 二. 创建 Spring MVC 项目1. 创建项目2. 用户和程序的映射3. 获取用户请求参数①. 获取单个参数②. 获取多个参数③. 传递对象④. 后端参数重命名&#xff08;后端参数映射&#xff09;R…

谈谈Android Jetpack Compose中的状态提升

谈谈Android Jetpack Compose中的状态提升 在本文中&#xff0c;我们将了解Jetpack Compose中的状态提升&#xff08;State Hoisting&#xff09;。在深入研究这个主题之前&#xff0c;让我们先了解一下Jetpack Compose中的有状态&#xff08;Stateful&#xff09;和无状态&am…

如何快速查询众多未签收快递单号

在日常工作中&#xff0c;快递查询是一个常见的任务。无论是电商卖家、快递员还是收件人&#xff0c;都需要查询快递的状态和信息。然而&#xff0c;一个一个地查询快递单号不仅耗时&#xff0c;还容易出错。因此&#xff0c;使用固乔快递查询助手这样的工具可以大大提高查询效…

Polygon zkEVM递归证明技术文档(5)——附录:借助SNARKjs和PIL-STARK实现proof composition

前序博客有&#xff1a; Polygon zkEVM递归证明技术文档&#xff08;1&#xff09;【主要描述了相关工具 和 证明的组合、递归以及聚合】Polygon zkEVM递归证明技术文档&#xff08;2&#xff09;—— Polygon zkEVM架构设计Polygon zkEVM递归证明技术文档&#xff08;3&#…