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. nest.js tutorials

    nest.js tutorials A progressive Node.js framework https://docs.nestjs.com//firststeps nest.js CLI ht ...

  2. how to create a style element in js (many ways)

    how to create a style element in js (many ways) create style in js Constructed StyleSheets CSSStyleS ...

  3. Flutter 使用高德地图定位

    amap_location 包 获取debug SHA1 // 使用debug.keystore获取debug SHA1 C:\Users\ajanuw\.android>keytool -li ...

  4. 智能合约稳定币USDN的价值在哪里?

    近几年来,区块链和数字货币市场快速发展,客观上需要价格相对稳定的交易媒介和贮藏手段,从而推动以链上资产或链下资产抵押型稳定币和算法型稳定币出现,以实现币价相对稳定的数字货币.市场上开始出现了诸如USD ...

  5. Renice INC:法国葡萄酒为什么独占世界鳌头?

    提起葡萄酒,许多人首先想到的就是法国.法国有着悠久的酿酒历史和精湛工艺,"82年的拉菲"几乎成了大众认识葡萄酒的代名词.市面上的进口葡萄酒琳琅满目,原产国众多,意大利.西班牙.美国 ...

  6. go-admin在线开发平台学习-3[细节解析]

    本章节主要的内容是对go-admin中的一些有趣编码进行分析,为自己以后提供一些借鉴 使用cli方式启动项目 使用cobra[眼镜蛇]完成强壮cli的工具,确保稳定. 使用cli的方式启动项目的好处显 ...

  7. 基于tcp的应用层消息边界如何定义

    聊聊基于tcp的应用层消息边界如何定义 背景 2018年笔者有幸接触一个项目要用到长连接实现云端到设备端消息推送,所以借机了解过相关的内容,最终是通过rabbitmq+mqtt实现了相关功能,同时在心 ...

  8. Mybatis-Plus插件配置

    yml配置 1 # Mybatis-Plus 2 mybatis-plus: 3 # 配置mapper的扫描,找到所有的mapper.xml映射文件 4 mapper-locations: com.x ...

  9. Asp.NET Core 限流控制-AspNetCoreRateLimit

    起因: 近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行:需要对提供的接口进行限流控制.避免因客户端频繁的请求导致服务器的压力. 一.AspNetCoreRateLimit 介 ...

  10. 永恒之蓝(MS17-010)检测与利用

    目录 利用Nmap检测 MSF反弹SHELL 注意 乱码 参考 利用Nmap检测 命令: nmap -p445 --script smb-vuln-ms17-010 [IP] # 如果运行报错,可以加 ...