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中删除一个值

  • 分三种情况:

    1. 没有左右子节点:

      • 可以直接删除
    2. 只有左子树或者只有右子树
      • 只需将上一个父节点的next指向他的唯一孩子即可
    3. 既有左子树又有右子树
      • 找到待删除节点的右子树的最小的那个值,与待删除的节点进行交换,然后把待删除的节点删除(这里只是进行值得交换,实际中一个节点可能包含多个域,应该要修改指针得指向,而不是简单得交换数据)
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(二叉搜索树)的基本操作的更多相关文章

  1. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...

  2. [LeetCode] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  3. bst 二叉搜索树简单实现

    //数组实现二叉树: // 1.下标为零的元素为根节点,没有父节点 // 2.节点i的左儿子是2*i+1:右儿子2*i+2:父节点(i-1)/2: // 3.下标i为奇数则该节点有有兄弟,否则又左兄弟 ...

  4. 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: BST树 ...

  5. [LeetCode] Minimum Absolute Difference in BST 二叉搜索树的最小绝对差

    Given a binary search tree with non-negative values, find the minimum absolute difference between va ...

  6. 浅析BST二叉搜索树

    2020-3-25 update: 原洛谷日报#2中代码部分出现一些问题,详情见此帖.并略微修改本文一些描述,使得语言更加自然. 2020-4-9 update:修了一些代码的锅,并且将文章同步发表于 ...

  7. 530 Minimum Absolute Difference in BST 二叉搜索树的最小绝对差

    给定一个所有节点为非负值的二叉搜索树,求树中任意两节点的差的绝对值的最小值.示例 :输入:   1    \     3    /   2输出:1解释:最小绝对差为1,其中 2 和 1 的差的绝对值为 ...

  8. LeetCode #938. Range Sum of BST 二叉搜索树的范围和

    https://leetcode-cn.com/problems/range-sum-of-bst/ 二叉树中序遍历 二叉搜索树性质:一个节点大于所有其左子树的节点,小于其所有右子树的节点 /** * ...

  9. Leetcode938. Range Sum of BST二叉搜索树的范围和

    给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和. 二叉搜索树保证具有唯一的值. 示例 1: 输入:root = [10,5,15,3,7,null,18], L = 7 ...

  10. 标准BST二叉搜索树写法

    本人最近被各种数据结构的实验折磨的不要不要的,特别是代码部分,对数据结构有严格的要求,比如写个BST要分成两个类,一个节点类,要给树类,关键是所以操作都要用函数完成,也就是在树类中不能直接操作节点,需 ...

随机推荐

  1. 微信小程序-云开发实战教程

    微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...

  2. 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 ...

  3. GitHub Actions

    GitHub Actions CI/CD & testing https://github.com/features/actions refs xgqfrms 2012-2020 www.cn ...

  4. Nestjs 验证对象数组

    route @Patch(':id') patch(@Param('id') id: string, @Body() removeEssayDto: RemoveEssayDto) { return ...

  5. Dart http库

    推荐下我写的一个http库ajanuw_http 最基本的获取数据 import 'package:http/http.dart' as http; main(List<String> a ...

  6. app启动速度怎么提升?

    简介: APP 启动速度的重要性不言而喻.高德地图是一个有着上亿用户的超级 APP,本文从唤端技术.H5 启动页.下载速度.APP加载.线程调度和任务编排等方面,详解相关技术原理和实现方案,分享高德在 ...

  7. 实用Macbook软件系列

    Macbook Software 实用Macbook软件系列 我的Mac都装了哪些软件 鉴于很多小伙伴刚刚由win系统转换到mac,一开始会有很多不适应的地方,所以本期文章准备给大家介绍下mac上一些 ...

  8. 怎么创建CSV文件和怎么打开CSV文件

    CSV(Comma Separated Values逗号分隔值). .csv是一种文件格式(如.txt..doc等),也可理解.csv文件就是一种特殊格式的纯文本文件.即是一组字符序列,字符之间已英文 ...

  9. 内核栈与thread_info结构详解

    本文转载自内核栈与thread_info结构详解 什么是进程的内核栈? 在内核态(比如应用进程执行系统调用)时,进程运行需要自己的堆栈信息(不是原用户空间中的栈),而是使用内核空间中的栈,这个栈就是进 ...

  10. 一些小Tip

    导语 个人感悟,持续更新中... 正文 无论NIO还是AIO,都没有在数据传输过程(tcp/udp)作革命性的创新.他们在传输过程的效率和传统BIO是一样的,还是会产生阻塞(网络延迟,Socket缓冲 ...