[模版总结] - 树的基本算法2 - BST

BST定义

BST - Binary Search Tree, 即二叉搜索树(有序二叉树)

特性

  • 中序遍历有序
  • 查找/插入/删除某个数值可以通过O(h) 即树的高度,最优logN,最坏 N.
    • 有多种改进BST可以动态维持插入删除后树结构能尽可能保持平衡

BST vs. 有序数组 vs. 普通数组 - 引用自 古城算法 https://www.youtube.com/watch?v=DpkTu2tU87o&list=PLbaIOC0vpjNVHmklf0nzPlPsNvJiqq1lZ&index=3

BST基本操作

查询 - 二分查找

  • 搜索数值 - 二分法
class Solution {public TreeNode searchBST(TreeNode root, int val) {while(root!=null) {if (root.val<val) {root = root.right;} else if (root.val>val) {root = root.left;} else {return root;}}return null;      }
}
  • 搜索临近数值
class Solution {double min = Double.MAX_VALUE;int res = -1;public int closestValue(TreeNode root, double target) {dfs(root, target);return res;}private void dfs(TreeNode root, double target) {if (root==null) return;if (Math.abs(root.val - target) < min) {min = Math.abs(root.val - target);res = root.val;} else if (Math.abs(root.val - target) == min) {res = root.val<res? root.val: res;}if (root.val>target) dfs(root.left, target);else dfs(root.right, target);}
}

插入

插入则是首先找到需要插入的位置,然后插入新结点

class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {return dfs(root, val);}private TreeNode dfs(TreeNode root, int val) {if (root==null) {root = new TreeNode(val);return root;}if (root.val > val) root.left = dfs(root.left, val);else root.right = dfs(root.right, val);return root; }
}

删除

删除操作较为复杂一点,我们在删除之后还需要维护当前二叉搜索树的性质,有三种情况:

  1. 删除叶子结点,不会影响BST性质,直接删除即可
  2. 删除结点没有右子树,也就是删除后左子树不会影响BST性质,将左子树root直接顶替删除结点的位置即可
  3. 删除结点有左右子树,为了保证BST性质,我们选择删除点的后继结点作为顶替结点,也就是删除结点右子树最左边的那个点,因为可以保证右子树所有点都大于该点,维持了BST性质
class Solution {public TreeNode deleteNode(TreeNode root, int key) {/**删除三种情况1. 叶子结点2. 只存在一个子树3. 左右都存在子树*/return dfs(root, key);}private TreeNode dfs(TreeNode root, int key) {if (root==null) return null;if (root.val==key) {if (root.left==null && root.right==null) return null;else if (root.left==null || root.right==null) {if (root.left!=null) return root.left;if (root.right!=null) return root.right;} else {// 找到root的后继结点,也就是右子树最左边的那个点TreeNode dum = root.right;while (dum.left!=null) {dum = dum.left;}root.val = dum.val;root.right = dfs(root.right, root.val);}} else if (root.val>key) {root.left = dfs(root.left, key);} else {root.right = dfs(root.right, key);}return root;}
}

前驱/后继结点

Leetcode 285

求解某一个点的前驱结点思路存储一个变量prev来保存进行下一层递归前的结点信息,如果中序遍历递归遍历到目标结点,其实保存的prev就是该结点的前驱结点

private void preSuccessor(TreeNode root, TreeNode p) {if (node==null) return;preSuccessor(node.left, p);if (root==p) return prev;prev = root;preSuccessor(node.right, p);
}

求解后躯结点较为复杂,需要考虑到几种情况:

  1. 目标结点有右子树,那么后继结点则是右子树中leftmost结点
  2. 如果目标结点没有右子树,那么后继结点则可能是parent中的某个结点

求解上述第二类后继结点思路类似,前驱结点是当前递归层处理的结点是目标结点时,prev保存的值即为前驱结点;后继结点可以理解为当前递归层的前驱结点时目标结点时,那么当前结点就是目标结点的后继结点,有点逆向思维哈哈。

 

class Solution {// 需要前驱结点信息TreeNode prev;TreeNode insuccessor;public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {if (p.right!=null) {TreeNode node = p.right;while (node.left!=null) {node = node.left;}return node;} else {helper(root, p);}return insuccessor;}private void helper(TreeNode node, TreeNode p) {if (node==null) return;helper(node.left, p);// check 当前结点if (prev!=null && prev==p) {insuccessor = node;}prev = node; //如果 当前结点前驱结点==p那么这个结点就是p的后驱结点helper(node.right, p);}
}

验证是否为BST

Leetcode 98. Validate BST

基本思路就是确保左结点 < 根结点 < 右结点,但是还需要保证局部正确的同时,左子树全部结点 < 根结点 < 右子树全部结点。所以每一次向下递归左子树时要以当前结点值作为上限值,遍历右子树时以当前结点值作为下限值

class Solution {public boolean isValidBST(TreeNode root) {return helper(root, null, null);}private boolean helper(TreeNode root, Integer low, Integer high) {if (root==null) return true;if ((low!=null && root.val<=low) || (high!=null && root.val>=high)) {return false;}return helper(root.left, low, root.val) && helper(root.right, root.val, high);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python-pptx教程之二操作已有PPT模板文件

文章目录 简单的案例找到要修改的元素修改幻灯片中的文本代码使用示例 修改幻灯片的图片代码使用示例 删除幻灯片代码使用示例 获取PPT中所有的文本内容获取PPT中所有的图片总结 在上一篇中我们已经学会了如何从零开始生成PPT文件&#xff0c;从零开始生成较为复杂的PPT是非常消…

php连接sqlserver 安装sqlserver 驱动windows系统

第一步下载Windows 上的 Microsoft ODBC Driver for SQL Server ODBC 驱动程序 Microsoft ODBC Driver for SQL Server 直接下载安装即可&#xff0c;安装后可查看安装版本 第二步&#xff1a;下载php_sqlsrv 驱动 安装解压后&#xff0c;会有对应php版本的驱动文件&#xf…

怎样备份电脑文件比较安全

域智盾软件是一款功能强大的电脑监控软件&#xff0c;它不仅具备实时屏幕监控、行为审计等功能&#xff0c;还能够对电脑文件进行备份和管理。下面将介绍域智盾软件如何备份电脑文件&#xff0c;以确保数据安全。 1、开启文档备份功能 部署后台&#xff0c;然后点击文档安全&a…

LT8711UXD 是一款高性能双通道 Type-C/DP1.4 至 HDMI2.0 转换器

1. 描述 LT8711UXD 是一款高性能双通道 Type-C/DP1.4 至 HDMI2.0 转换器&#xff0c;设计用于将 USB Type-C 源或 DP1.4 源连接至 HDMI2.0 接收器。LT8711UXD 集成了一个 DP1.4 兼容接收器和一个 HDMI2.0 兼容发射器。此外&#xff0c;还包括两个 CC 控制器用于 CC 通信以实现…

什么是原生IP与广播IP?如何区分判定?

在代理IP中&#xff0c;我们常常听到原生IP与广播IP&#xff0c;二者有何区别&#xff1f;如何区分呢&#xff1f;下面为大家详细讲解。 一、什么是原生ip 原生IP地址是互联网服务提供商&#xff08;ISP&#xff09;直接分配给用户的真实IP地址&#xff0c;无需代理或转发。此…

不允许你还不了解指针的那些事(二)(从入门到精通看这一篇就够了)(数组传参的本质+冒泡排序+数组指针+指针数组)

目录 数组名的理解 使用指针访问数组 一维数组传参的本质 冒泡排序 二级指针 指针数组 指针数组模拟二维数组 字符指针变量 数组指针变量 二维数组传参的本质 函数指针变量 函数指针变量的创建 函数指针变量的使用 两段有趣的代码 代码一 代码二 typedef关键字 函数指针数组 …

整理笔记——MOS管、三极管、IGBT

一、MOS管 在实际生活要控制点亮一个灯&#xff0c;例如家里的照明能&#xff0c;灯和电源之间就需要一个开关需要人为的打开和关闭。 再设计电路板时&#xff0c;如果要使用MCU来控制一个灯的开关&#xff0c;通常会用mos管或是三极管来做这个开关元件。这样就可以通过MCU的信…

计及源荷不确定性的综合能源生产单元运行调度与容量配置随机优化模型MATLAB

主要内容 本程序复现《计及源荷不确定性的综合能源生产单元运行调度与容量配置两阶段随机优化》模型&#xff0c;采用全年光伏、风电数据通过kmeans聚类得到6种场景&#xff0c;构建了随机优化模型&#xff0c;在研究融合P2G与CCS的IEPU系统框架基础上&#xff0c;建立了各关键…

linux关于cmake,makefile和gdb的使用

c文件的编译 安装环境(centos 7) 检查命令是否齐全 gcc --version g --version gdb–version 安装命令 yum -y install gcc-c安装g命令&#xff08;用于编译c/c文件&#xff09; yum -y install gcc安装gcc命令(用于编译c文件&#xff09; 每个都出现版本号&#xff0c;证明…

深度学习入门(第四天)——递归神经网络与词向量原理解读

一、RNN网络架构解读 常规神经网络并不能考虑时间序列的特征&#xff08;比如前天昨天今天或者带有前后关联的特征&#xff09;&#xff0c;现在每个特征都是独立考虑的&#xff0c;那么如果有这样的特征&#xff0c;网络应该怎么学呢 而递归递归网络hidden这里的转回箭头&…

C/C+=内存管理

C/C内存管理以及动态内存的申请_c动态内存的申请与释放_Demo Test的博客-CSDN博客 问题是&#xff0c;这个0x0804 8000 到0xC 0000 0000之间&#xff0c;不止3GB&#xff0c;应该有47GB&#xff0c;该怎么解释呢&#xff1f;

4.1 Windows驱动开发:内核中进程与句柄互转

在内核开发中&#xff0c;经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符&#xff08;PID&#xff09;来标识&#xff0c;而句柄是指对内核对象的引用。在Windows内核中&#xff0c;EProcess结构表示一个进程&#xff0c;而HANDLE是一个句柄。 为了实…