【二叉搜索树定义】(BST)

二叉搜索树(Binary Search Tree,简称 BST)是一种很常用的的二叉树。它的定义是:一个二叉树中,任意节点的值要大于等于左子树所有节点的值,且要小于等于右边子树的所有节点的值。

【二叉树算法框架】

void traverse(TreeNode root) {// root 需要做什么?在这做。// 其他的不用 root 操心,抛给框架traverse(root.left);traverse(root.right);
}

【二叉搜索树算法框架】

void BST(TreeNode root, int target) {if (root.val == target)// 找到目标,做点什么if (root.val < target) BST(root.right, target);if (root.val > target)BST(root.left, target);
}

【问题描述】

实现 BST 的基础操作:判断 BST 的合法性、增、删、查。

【解答思路】

1. 判断 BST 的合法性

root 需要做的不只是和左右子节点比较,而是要整个左子树和右子树所有节点比较。

boolean isValidBST(TreeNode root) {return isValidBST(root, null, null);
}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;return isValidBST(root.left, min, root) && isValidBST(root.right, root, max);
}
2. 在 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);
}

利用特性

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);if (root.val > target)return isInBST(root.left, target);// root 该做的事做完了,顺带把框架也完成了,妙
}
3. 在 BST 中插入一个数

对数据结构的操作无非遍历 + 访问,遍历就是“找”,访问就是“改”。具体到这个问题,插入一个数,就是先找到插入位置,然后进行插入操作。
直接套BST 中的遍历框架,加上“改”的操作即可。一旦涉及“改”,函数就要返回 TreeNode 类型,并且对递归调用的返回值进行接收。

void BST(TreeNode root, int target) {if (root.val == target)// 找到目标,做点什么if (root.val < target) BST(root.right, target);if (root.val > target)BST(root.left, target);
}
4. 在 BST 中删除一个数

TreeNode deleteNode(TreeNode root, int key) {if (root == null) return null;if (root.val == key) {// 这两个 if 把情况 1 和 2 都正确处理了if (root.left == null) return root.right;if (root.right == null) return root.left;// 处理情况 3TreeNode minNode = getMin(root.right);root.val = minNode.val;root.right = deleteNode(root.right, minNode.val);} else if (root.val > key) {root.left = deleteNode(root.left, key);} else if (root.val < key) {root.right = deleteNode(root.right, key);}return root;
}TreeNode getMin(TreeNode node) {// BST 最左边的就是最小的while (node.left != null) node = node.left;return node;
} 

注意一下,这个删除操作并不完美,因为我们一般不会通过 root.val = minNode.val 修改节点内部的值来交换节点,而是通过一系列略微复杂的链表操作交换 root 和 minNode 两个节点。因为具体应用中,val 域可能会很大,修改起来很耗时,而链表操作无非改一改指针,而不会去碰内部数据。

【总结】

1. 二叉树算法设计的总路线:把当前节点要做的事做好,其他的交给递归框架,不用当前节点操心。
2.如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表,借助参数传递信息。
3.在二叉树框架之上,扩展出一套 BST 遍历框架
void BST(TreeNode root, int target) {if (root.val == target)// 找到目标,做点什么if (root.val < target) BST(root.right, target);if (root.val > target)BST(root.left, target);
}

转载链接:https://leetcode-cn.com/problems/same-tree/solution/xie-shu-suan-fa-de-tao-lu-kuang-jia-by-wei-lai-bu-/

[Leetcode][第98 450 700 701题][JAVA][二叉搜索树的合法性、增、删、查][递归][深度遍历]相关推荐

  1. [剑指offer]面试题第[54]题[JAVA][二叉搜索树的第k大节点][递归][迭代]

    [问题描述][简单] 给定一棵二叉搜索树,请找出其中第k大的节点.示例 1: 输入: root = [3,1,4,null,2], k = 13/ \1 4\2 输出: 4 示例 2:输入: root ...

  2. [剑指offer]面试题第[68-2]题[Leetcode][第236题][JAVA][二叉搜索树的最近公共祖先][递归]

    [问题描述][中等] 235/68-1 搜索二叉树 236/68-2 二叉树 [解答思路] 递归 时间复杂度:O(N) 空间复杂度:O(N) 情况 1. , 2. , 3. , 4. 的展开写法如下. ...

  3. LeetCode腾讯精选练习50题-235.二叉搜索树的最近公共祖先

    题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先的定义为: 对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...

  4. [剑指offer]面试题第[36]题[JAVA][二叉搜索树与双向链表][递归]

    [问题描述][中等] [解答思路] 中序遍历 时间复杂度:O(N) 空间复杂度:O(N) class Solution {Node pre, head;public Node treeToDoubly ...

  5. [Leedcode][JAVA][第98题][验证二叉搜索树]

    [问题描述][第98题][验证二叉搜索树][中等] 给定一个二叉树,判断其是否是一个有效的二叉搜索树.假设一个二叉搜索树具有如下特征:节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节 ...

  6. 牛客题霸 [二叉搜索树的第k个结点]C++题解/答案

    牛客题霸 [二叉搜索树的第k个结点]C++题解/答案 题目: 给定一棵二叉搜索树,请找出其中的第k小的结点. 题解: 二叉搜索树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它 ...

  7. LeetCode 之 JavaScript 解答第98题 —— 验证二叉搜索树(Validate Binary Search Tree)

    Time:2019/4/24 Title: Vaildata Binary Search Tree Difficulty: Medium Author: 小鹿 题目:Vaildata Binary S ...

  8. LeetCode简单题之二叉搜索树的最小绝对差/最小距离

    题目 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 差值是一个正数,其数值等于两值之差的绝对值. 示例 1: 输入:root = [4,2,6,1,3] 输出: ...

  9. LeetCode简单题之二叉搜索树的范围和

    题目 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例 1: 输入:root = [10,5,15,3,7,null,18], low = 7, ...

最新文章

  1. 2021年大数据Flink(二十):案例二 基于数量的滚动和滑动窗口
  2. python窗口显示图片imread() imshow()_Python-OpenCV学习之imread,imshow
  3. Android PhoneGap源码分析——白名单
  4. jQuery与CSS3的选择器
  5. php修改文件上传大小限制
  6. VS Code Element 提示 VSCode-Element-Helper 插件
  7. 城市大数据:内涵、服务架构与实施路径
  8. 许海燕(1987-),女,宁波市智慧城市规划标准发展研究院研究人员.
  9. 双栏模板图片标题无法居中_没想到吧,只用一张图片,你就可以做一份PPT!
  10. 利用melendy插入参考文献_如何利用mendeley搞定SCI论文参考文献,这篇一定要看
  11. render注册一个链接组件_详解vue 动态加载并注册组件且通过 render动态创建该组件...
  12. keras padding_GAN整体思路以及使用Keras搭建DCGAN
  13. python cls
  14. mysql objectid_MongoDB 的objectid和UUID
  15. UVa 10815 - Andy's First Dictionary
  16. 实战:使用python爬取新冠疫情国内外最新数据
  17. Windows解压文件名乱码解决方法
  18. android 仿微信demo————微信顶部操作栏搜索按钮实现(查询通讯录好友功能)
  19. iPhone 如何将图片转换为文字
  20. php如何上传doc文件,php实现将上传word文件转为html的方法

热门文章

  1. python安装lxml,在windows环境下
  2. LetCode-MySql删除重复的电子邮箱
  3. saltstack部署java应用失败无日志——CICD 部署
  4. Will not attempt to authenticate using SASL | dubbo项目启动特别慢,拉取 zookeeper 服务日志打印特别慢
  5. 汇编64讲(搞免杀、破解必看)
  6. java 读取csv_Java读取CSV的常用方法 | 学步园
  7. sql服务器如何复制数据库文件,如何将架构和一些数据从SQL Server复制到另一个实例?...
  8. jquery 一些特效使用
  9. 关于操作系统的学习总结
  10. 怎么在电脑安装php文件夹在哪个文件夹,php进行文件上传时找不到临时文件夹怎么办,电脑自动保存的文件在哪里...