BST(二叉搜索树)的基本操作
BST(二叉搜索树)
- 首先,我们定义树的数据结构如下:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
一、判断BST的合法性
二叉搜索树的左子树节点都比父节点要小、右子树节点都比父节点要大;每一个子树都是BST。
我们遍历的时候如果只比较父节点和他的子节点大小的话,会有bug:
public boolean isValidBST(TreeNode root, TreeNode min, TreeNode max) {
if (root == null) {
return true;
}
if (min != null && root.val <= root.left.val) {
return false;
}
if (max != null && root.val >= root.right.val) {
return false;
}
return isValidBST(root.left, min, root) && isValidBST(root.right, root, max);
}
对于这样子的树,确实满足左子树小于父节点,右子树大于父节点,但是却不是一个BST,所以我们使用两个辅助参数来解决这个问题:
public boolean isValidBST(TreeNode root) {
return isValidBST(root, null, null);
}
public boolean isValidBST(TreeNode root, TreeNode min, TreeNode max) {
if (root == null) {
return true;
}
if (min != null && root.val <= min.val) {
return false;
}
if (max != null && root.val >= max.val) {
return false;
}
// 左子树不得大于max边界,右子树不得小于min边界,就能得到正确结果了
return isValidBST(root.left, min, root) && isValidBST(root.right, root, max);
}
二、在BST中查找目标值
直接暴力全部搜索:
boolean isInBST(TreeNode root, int target) {
if (root == null) {
return false;
}
if (root.val == target) {
return true;
}
return isInBST(root.left, target) || isInBST(root.right, target);
}
但是BST有左小右大的这个特性,于是可以运用类似二分的思想,只需要将target和当前结点值比较,如果小于,就搜索左边,右边就可以不用搜索,反之:
boolean isInBST(TreeNode root, int target) {
if (root == null) {
return false;
}
if (root.val == target) {
return true;
}
if (root.val < target) {
return isInBST(root.right, target);
} else {
return isInBST(root.left, target);
}
}
三、在BST中插入一个值
TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) {
return new TreeNode(val);
}
if (root.val == val) {
return root;
}
// 比节点的值大
if (root.val < val) {
root.right = insertIntoBST(root.right, val);
}
// 比节点的值小
if (root.val > val) {
root.left = insertIntoBST(root.left, val);
}
return root;
}
四、在BST中删除一个值
- 分三种情况:
- 没有左右子节点:
- 可以直接删除
- 只有左子树或者只有右子树
- 只需将上一个父节点的next指向他的唯一孩子即可
- 既有左子树又有右子树
- 找到待删除节点的右子树的最小的那个值,与待删除的节点进行交换,然后把待删除的节点删除(这里只是进行值得交换,实际中一个节点可能包含多个域,应该要修改指针得指向,而不是简单得交换数据)
- 没有左右子节点:
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (root.val == key) {
// 删除
// 如果只有一个或者没有子树得情况
if (root.left == null) {
return root.right;
}
if (root.right == null) {
return root.left;
}
// 当既有左子树又有右子树时
// 这里只是进行值交换,应该进行指针修改
TreeNode minNode = getMin(root);
root.val = minNode.val;
// 删除交换后得节点,相当于此时待删除节点又跑到末尾去了
root.right = deleteNode(root.right, key);
} else if (root.val > key) {
// 去左子树找
root.left = deleteNode(root.left, key);
} else if (root.val < key) {
// 去右子树找
root.right = deleteNode(root.right, key);
}
return root;
}
public TreeNode getMin(TreeNode node) {
while (node.left != null) {
node = node.left;
}
return node;
}
BST(二叉搜索树)的基本操作的更多相关文章
- 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...
- [LeetCode] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- bst 二叉搜索树简单实现
//数组实现二叉树: // 1.下标为零的元素为根节点,没有父节点 // 2.节点i的左儿子是2*i+1:右儿子2*i+2:父节点(i-1)/2: // 3.下标i为奇数则该节点有有兄弟,否则又左兄弟 ...
- 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: BST树 ...
- [LeetCode] Minimum Absolute Difference in BST 二叉搜索树的最小绝对差
Given a binary search tree with non-negative values, find the minimum absolute difference between va ...
- 浅析BST二叉搜索树
2020-3-25 update: 原洛谷日报#2中代码部分出现一些问题,详情见此帖.并略微修改本文一些描述,使得语言更加自然. 2020-4-9 update:修了一些代码的锅,并且将文章同步发表于 ...
- 530 Minimum Absolute Difference in BST 二叉搜索树的最小绝对差
给定一个所有节点为非负值的二叉搜索树,求树中任意两节点的差的绝对值的最小值.示例 :输入: 1 \ 3 / 2输出:1解释:最小绝对差为1,其中 2 和 1 的差的绝对值为 ...
- LeetCode #938. Range Sum of BST 二叉搜索树的范围和
https://leetcode-cn.com/problems/range-sum-of-bst/ 二叉树中序遍历 二叉搜索树性质:一个节点大于所有其左子树的节点,小于其所有右子树的节点 /** * ...
- Leetcode938. Range Sum of BST二叉搜索树的范围和
给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和. 二叉搜索树保证具有唯一的值. 示例 1: 输入:root = [10,5,15,3,7,null,18], L = 7 ...
- 标准BST二叉搜索树写法
本人最近被各种数据结构的实验折磨的不要不要的,特别是代码部分,对数据结构有严格的要求,比如写个BST要分成两个类,一个节点类,要给树类,关键是所以操作都要用函数完成,也就是在树类中不能直接操作节点,需 ...
随机推荐
- 微信小程序-云开发实战教程
微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...
- You Don't Know the Hack tech in the frontend development
You Don't Know the Hack tech in the frontend development 你所不知道的前端黑科技 css in js animation https://www ...
- GitHub Actions
GitHub Actions CI/CD & testing https://github.com/features/actions refs xgqfrms 2012-2020 www.cn ...
- Nestjs 验证对象数组
route @Patch(':id') patch(@Param('id') id: string, @Body() removeEssayDto: RemoveEssayDto) { return ...
- Dart http库
推荐下我写的一个http库ajanuw_http 最基本的获取数据 import 'package:http/http.dart' as http; main(List<String> a ...
- app启动速度怎么提升?
简介: APP 启动速度的重要性不言而喻.高德地图是一个有着上亿用户的超级 APP,本文从唤端技术.H5 启动页.下载速度.APP加载.线程调度和任务编排等方面,详解相关技术原理和实现方案,分享高德在 ...
- 实用Macbook软件系列
Macbook Software 实用Macbook软件系列 我的Mac都装了哪些软件 鉴于很多小伙伴刚刚由win系统转换到mac,一开始会有很多不适应的地方,所以本期文章准备给大家介绍下mac上一些 ...
- 怎么创建CSV文件和怎么打开CSV文件
CSV(Comma Separated Values逗号分隔值). .csv是一种文件格式(如.txt..doc等),也可理解.csv文件就是一种特殊格式的纯文本文件.即是一组字符序列,字符之间已英文 ...
- 内核栈与thread_info结构详解
本文转载自内核栈与thread_info结构详解 什么是进程的内核栈? 在内核态(比如应用进程执行系统调用)时,进程运行需要自己的堆栈信息(不是原用户空间中的栈),而是使用内核空间中的栈,这个栈就是进 ...
- 一些小Tip
导语 个人感悟,持续更新中... 正文 无论NIO还是AIO,都没有在数据传输过程(tcp/udp)作革命性的创新.他们在传输过程的效率和传统BIO是一样的,还是会产生阻塞(网络延迟,Socket缓冲 ...