二叉搜索树的实现

news2024/11/14 21:24:25
  1. 什么是二叉搜索树

1.若它的左子树不为空,那么左子树上所有节点都小于根节点
2.若它的右子树不为空,那么右子树上所有节点都小于根节点
3.它的左右子树也分别是二叉搜索树
4.使用中序遍历结果是从小到大

定义节点,使用静态内部类
static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val) {
            this.val = val;
        }
    }
    public TreeNode root;//根节点
  1. 查找二叉搜索树是否有值为key的节点

遍历二叉搜索树,如果节点的值比key小,就往右边走,反之就往左边走
public TreeNode search(int key) {
        if(root == null) {
            return null;
        }
        TreeNode cur = root;
        while(cur != null) {
            if(cur.val == key) {
                return cur;
            }else if(key > cur.val) {
                cur = cur.right;
            }else {
                cur = cur.left;
            }
        }
        return null;
    }
  1. 二叉搜索树的插入

在二叉树中插入的新节点都是在叶子上,并且不能插入相同数据的节点
从根节点开始比较,如果比该节点大就往右边走,反之往左边走,直到走到叶子节点。

public boolean insert(int key) {
        TreeNode node = new TreeNode(key);
        if(root == null) {
            root = node;
            return true;
        }
        TreeNode cur = root;
        TreeNode parent = null;//要插入节点的父亲节点
        while(cur != null) {
            if(cur.val == node.val) {
                return false;
            }else if(node.val > cur.val) {
                parent = cur;
                cur = cur.right;
            }else {
                parent = cur;
                cur = cur.left;
            }
        }
        //如果比父亲节点大放右边,反之放左边
        if(parent.val < node.val) {
            parent.right = node;
        }else {
            parent.left = node;
        }
        return true;
    }
  1. 二叉搜索树的删除(难点)

设待删除结点为 cur, 待删除结点的双亲结点为 parent
1. cur.left == null
(1) cur 是 root,则 root = cur.right
2)cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
3) cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
2. cur.right == null
1) cur 是 root,则 root = cur.left
2) cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
3) cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
3. cur.left != null && cur.right != null
需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题

我结合画图和代码7个条件一个一个分析过去,别担心
  1. 在cur.left==null的前提下

  1. 在cur.right == null的前提下

  1. cur.left != null && cur.right != null

有两种选择,任选一种。1.去要删除节点cur的左子树找最大值的节点覆盖cur,因为是最大的节点,所以该节点没有右子树,也就是把它当作前面第二种情况来做。
2.去cur的右子树中找最小值的节点覆盖cur,因为是cur右子树的最小节点,所以该节点一定没有左子树,可以把它当作第一种情况来做

我的代码是选择第二个

删除的所有代码如下
/**
     * 删除值为key的节点
     * @param key
     */
    public void remove(int key) {
        if(root == null) {
            return;
        }
        TreeNode cur = root;
        TreeNode parent = null;//要删除节点的父亲节点
        while(cur != null) {
            if(key > cur.val) {
                parent = cur;
                cur = cur.right;
            }else if(key < cur.val) {
                parent = cur;
                cur = cur.left;
            }else {
                //找到了
                removeNode(cur, parent);
                return;
            }
        }
    }

    /**
     * 删除节点
     * @param cur 要删除的节点
     * @param parent 要删除的父亲节点
     */
    private void removeNode(TreeNode cur, TreeNode parent) {
        //要删除节点的左子树为空
        if(cur.left == null) {
            //要删除节点是根节点
            if(cur == root) {
                root = root.right;
            }else if(parent.left == cur) {
                //要删除节点是父亲节点的左节点
                parent.left = cur.right;
            }else {
                //要删除节点是父亲节点的右节点
                parent.right = cur.right;
            }
        }else if(cur.right == null) {//要删除节点的右子树为空
            if(cur == root) {
                //要删除节点是根节点
                root = root.left;
            }else if(parent.left == cur) {
                //要删除节点的是父亲节点的左节点
                parent.left = cur.left;
            }else {
                //要删除节点是父亲节点的右节点
                parent.right = cur.left;
            }
        }else {
            //要删除节点的左右子树都不为空
            //使用替换删除的方式进行删除
            //要么在要删除节点的左子树中找到最大值,该节点的右子树一定为空,用它替换cur,
            //要么在要删除节点的右子树中找到最小值,该节点的左子树一定为空,用它替换cur
            //1.找到要替换的节点,采用找右子树的最小值进行替换
            TreeNode target = cur.right;//要找的节点用来替换的节点
            TreeNode targetParent = cur;//用来替换的节点的父亲节点
            while(target.left != null) {
                targetParent = target;
                target = target.left;
            }
            //target节点没有左子树,因为target是最小的,所以又来到上面要删除节点的左子树为空的情况
            cur.val = target.val;
            if(targetParent.left == target) {
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }
  1. 性能分析

无论是插入还是删除都要进行查找,也就是说查找效率越高二叉搜索树的性能就越高。而二叉树搜索树是满二叉树的情况下,树的高度低,时间复杂度O(log2N).极端条件下,二叉搜索树编程单支树就是O(n).所以为了避免这种不平衡的情况,前辈们做了升级变成AVL树就是一棵高度平衡的二叉搜索树,最大高度差只有1.但是为了保证高度差为1付出的代价太大,又引入了红黑树,.

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

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

相关文章

http组成及状态及参数传递

http组成及状态及参数传递 早期的网页都是通过后端渲染来完成的&#xff1a;服务器端渲染&#xff08;SSR&#xff0c;server side render&#xff09;&#xff1a; 客户端发出请求 -> 服务端接收请求并返回相应HTML文档 -> 页面刷新&#xff0c;客户端加载新的HTML文档&…

7综合项目 旅游网 【7.精选分类】

精选旅游人气旅游→收藏次数最高最新旅游→日期最新主题旅游→主题关键字相同在首页将精选的内容动态展示的实现分析首页中的精选包含“人气旅游”、“最新旅游”、“主题旅游”三个部分index.html//页面加载完成,发送ajax请求根据点击不同分类展示不同内容人气旅游→收藏次数最…

分享17个提升开发效率的工具“轮子”

本文是向大家介绍平时在开发中经常用到的小工具&#xff0c;它能够极大得提升我们的开发效率&#xff0c;能够解决平时开发中遇到的问题。前言在java的庞大体系中&#xff0c;其实有很多不错的小工具&#xff0c;也就是我们平常说的“轮子“。如果在我们的日常工作当中&#xf…

数据结构课程设计:高铁信息管理系统(C++实现)

目录 简介实验输出实验要求代码运行环境结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖…

嵌入式Linux驱动开发(一)chrdevbase虚拟字符设备

Linux下三大驱动&#xff1a;字符设备&#xff0c;块设备&#xff0c;网络设备。一个硬件可以从属于不同的设备分类。 0. Linux应用程序对驱动程序的调用流程 驱动加载成功后会在/dev目录下生成一个文件&#xff0c;对该文件的操作就是对设备的操作。当我们在用户态调用一个函…

Element-UI实现复杂table表格结构

Element-UI组件el-table用于展示多条结构类似的数据&#xff0c;可对数据进行排序、筛选、对比或其他自定义操作。将使用到以下两项&#xff0c;来完成今天demo演示&#xff1a;多级表头&#xff1a;数据结构比较复杂的时候&#xff0c;可使用多级表头来展现数据的层次关系。合…

Web3中文|Web3CN加速器第二期「Web3项目征集」火热报名

Web3CN加速器第二期「Web3项目征集」火热征集中&#xff0c;本次征集活动是由Web3CN加速器联合专业web3媒体Web3CN、VC机构Tiger VC DAO核心发起&#xff0c;数百家加密VC机构、加密社区等联合发起的&#xff0c;为早期Web3创新创业项目提供加速服务。如果你正在进行web3相关的…

VC常见问题(.obj : error LNK2019、fatal error C1083、编译64位Detours)

VC常用问题VC常见问题*.obj : error LNK2019: 无法解析的外部符号 __imp_FindWindow ,该符号在函数 YAWindows环境下用nmake编译常见问题fatal error C1083: 无法打开包括文件:“excpt.h”vs2012编译64位Detours&#xff08;其他vs版本同理&#xff09;vs项目设置选项编译使用了…

Java基础面试题(三)

Java基础面试题 一、JavaWeb专题 1.HTTP响应码有哪些 1、1xx&#xff08;临时响应&#xff09; 2、2xx&#xff08;成功&#xff09; 3、3xx&#xff08;重定向&#xff09;&#xff1a;表示要完成请求需要进一步操作 4、4xx&#xff08;错误&#xff09;&#xff1a;表示请…

Nuxt实战教程基础-Day01

Nuxt实战教程基础-Day01Nuxt是什么&#xff1f;Nuxt.js框架是如何运作的&#xff1f;Nuxt特性流程图服务端渲染(通过 SSR)单页应用程序 (SPA)静态化 (预渲染)Nuxt优缺点优点缺点安装运行项目总结前言&#xff1a;本教程基于Nuxt2&#xff0c;作为教程的第一天&#xff0c;我们先…

BUUCTF-[RoarCTF2019]polyre

题目下载&#xff1a;下载 这道题目是一个关于控制流平坦化和虚假流程。 首先了解一下控制流平坦化&#xff1a;利用符号执行去除控制流平坦化 - 博客 - 腾讯安全应急响应中心https://www.cnblogs.com/zhwer/p/14081454.htmlbuuctf RoarCTF2019 polyre writeup - 『脱壳破解区…

单点登录的几种实现方式探讨

单点登录&#xff08;Single Sign On&#xff09;&#xff0c;简称为 SSO&#xff0c;是解决企业内部的一系列产品登录问题的方案。SSO 的定义是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统&#xff0c;用于减少用户重复的登录操作&#…

PyTorch的自动微分(autograd)

PyTorch的自动微分(autograd) 计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量、矩阵、张量 边表示运算&#xff0c;如加减乘除卷积等 用计算…

共话开源 | 开放原子开源基金会专题调研openKylin社区!

3月8日&#xff0c;开放原子开源基金会秘书长冯冠霖、运营部部长李博、业务发展部部长朱其罡、研发部副部长周济一行莅临openKylin社区调研交流&#xff0c;麒麟软件高级副总经理韩乃平、副总裁董军平、终端研发部副总经理陆展、产品规划部经理常亚武、市场与政府事务部高级经理…

力扣sql简单篇练习(二十五)

力扣sql简单篇练习(二十五) 1 无效的推文 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT tweet_id FROM Tweets WHERE CHAR_LENGTH(content)>151.3 运行截图 2 求关注者的数量 2.1 基本题目内…

【Linux实战篇】二、在Linux上部署各类软件

一、实战章节&#xff1a;在Linux上部署各类软件 二、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统&#xff08;后续简称MySQL&#xff09;&#xff0c;是一款知名的数据库系统&#xff0c;其特点是&#xff1a;轻量、简单、功能丰富。 MySQL数据库可谓是…

在矩池云运行 Stable Diffusion web UI,使用v1.5模型和 ControlNet 插件

今天给大家介绍下如何在矩池云使用 Stable Diffusion web UI v1.5 模型和 Stable Diffusion ControlNet 插件。 租用机器 租用机器需要选择内存大于8G的机器&#xff0c;比如 A2000&#xff0c;不然 Stable Diffusion web UI 启动加载模型会失败。&#xff08;Killed 内存不足…

近20个省市加快房屋网签备案,君子签电子签章助推掌上办理

2020年以来&#xff0c;上海、北京、深圳、长沙、武汉、杭州、山东、郑州、西安、佛山、青岛、江门、昆明、韶关、南京、石家庄等全国近20个省市纷纷响应住建部政策要求&#xff0c;鼓励使用电子签名、电子签章等技术加快推动商品房、二手房或租赁房交易合同网签备案&#xff0…

是面试官放水,还是公司实在是太缺人?这都没挂,字节原来这么容易进...

字节是大企业&#xff0c;是不是很难进去啊&#xff1f;” “在华为做软件测试&#xff0c;能得到很好的发展吗&#xff1f; 一进去就有10K&#xff0c;其实也没有想的那么难” 直到现在&#xff0c;心情都还是无比激动&#xff01; 本人211非科班&#xff0c;之前在字节和腾讯…

UEFI开发探索101 – PCD探究(helloworld中的使用)

2 如何使用PCD PCD可以使用于UEFI存在的大部分时间&#xff0c;除了在SEC阶段、早期的PEI和DXE阶段&#xff0c;基本都可以访问。在使用前&#xff0c;我们需要搞清楚PCD的结构和类型。 2.1 PCD的类型 PCD变量的格式有点像结构体&#xff1a; TokenSpaceGuidCName.PcdCName …