目录

搜索树

1.概念

2. 操作-查找

3. 操作-插入

4. 操作-删除

5. 代码实现


搜索树

1.概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

2. 操作-查找

查找规律:

若根节点不为空:

如果根节点val = 查找val,返回true

如果根节点val > 查找val,从该节点左子树查找

如果根节点val < 查找val,从该节点右子树查找

若最后根节点为空,返回false

3. 操作-插入

1.如果树为空树,即根为null,就可以直接插入。

2.如果树非空树,应按照查找逻辑找到插入位置,插入新节点。

通过查找的规则来寻找插入节点,每次插入的节点都为叶子节点! 

        注意相同的key是不可以插入的!

从根节点开始,根据查找的规则用cur进行节点遍历,同时用prev来存储遍历的前一个节点,直到cur == null时,此时prev已经遍历到叶子节点,再进行判断key与该叶子节点的大小关系来决定放在left还是right。

4. 操作-删除

设待删除结点为 cur, 待删除结点的双亲结点为 parent

分为三种情况:

1. cur.left == null
2. cur.right == null
3. cur.left != null && cur.right != null

1. cur.left == null

1. cur 是 root,则 root = cur.right

 2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.right

 3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.right

2. cur.right == null

1. cur 是 root,则 root = cur.left

 2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.left

3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.left  

3. cur.left != null && cur.right != null 

对于这一种情况,我们采用替罪羊的方式进行删除,即寻找要删除节点的左子树的最右端的一个节点,该节点的val为左子树的最大值,同时也满足小于要删除节点的右子树的所有节点,用该值填补到被删除节点,所以问题就转变为:处理这个替换节点原位置的删除问题了。而这个替换节点作为左子树的最右端,它的 right 为 null ,所以就是上述cur.right == null这一种情况了,问题也就迎刃而解了。

或者寻找要删除节点的右子树的最左端的一个节点(中序下的第一个结点),该节点的val为右子树的最小值,同时也满足大于要删除节点的左子树的所有节点。用该值填补到被被删除节点,再处理这个替换节点原位置的删除问题了。这个替换节点作为右子树的最左端,它的 left 为 null ,也就是上述cur.left == null这一种情况了。

如删除上图的cur,可以采用以下两种方式。

易错点!!!

此时,还有一种特殊情况需要注意,以右树最左节点为例:tmp=cur.right

在上述的讨论情况中,到最后删除替换节点原位置这一阶段时,我们采用parent.left =  tmp.right的方法,如下图情况一。

但此时我们忽略了另一种情况:一开始的接收到的tmp就已经是右子树的最左端了,如下图情况二。此时要删除替换节点原位置的时候,就不可以再用parent.left =   tmp.right这条语句了!!!而应该用parent.right = tmp.right。

所以再完成代码的时候应该添加判断语句parent.right == tmp,成立实现情况二,不成立实现情况一。(结合下面代码分析效果更佳)

5. 代码实现

class BinarySearchTree{static class TreeNode{public int val;public TreeNode left;public TreeNode right;public TreeNode(int val){this.val = val;}}public TreeNode root = null;/*** 查找一个val 是不是在当前的搜索树当中* @param val* @return 有返回 没有返回null*/public boolean search(int val){TreeNode cur = root;while (cur != null){if (cur.val<val){cur = cur.right;} else if (cur.val>val) {cur = cur.left;}else{return true;}}return false;}//中序遍历public void inorder(TreeNode root){if (root == null){return;}inorder(root.left);System.out.print(root.val+" ");inorder(root.right);}/*** 插入元素key* @param key* @return* 每次插入都是插入在叶子结点!!!!*/public boolean insert(int key){if (root == null){root = new TreeNode(key);return true;}TreeNode cur = root;TreeNode prev = null;while (cur!=null){if (cur.val>key){prev = cur;cur = cur.left;}else if (cur.val<key){prev = cur;cur = cur.right;}else {return false;   //相同的key是不能进行插入的}}//cur = null 了//判断key大于prev还是小于prev来判断在左边还是右边TreeNode newNode = new TreeNode(key);if (key> prev.val){prev.right = newNode;}else{prev.left = newNode;}return true;}public void remove(int key){TreeNode cur = root;TreeNode prev = null;while (cur!=null){if (key> cur.val){prev = cur;cur = cur.right;} else if (key< cur.val) {prev = cur;cur = cur.left;}else {removeNode(cur,prev);return;}}}public void removeNode(TreeNode cur,TreeNode prev){if (cur.left == null){                  //该节点左边为nullif (cur == root){                   //该节点为根结点root = cur.right;} else if (cur == prev.left) {      //该节点为prev的左边prev.left = cur.right;}else {                             //该节点为prev的右边prev.right = cur.right;}} else if (cur.right == null) {         //该节点右边为nullif (cur == root){root = cur.left;} else if (cur == prev.left) {prev.left = cur.left;}else {prev.right = cur.left;}}else{                                  //该节点左右两边都不为nullTreeNode tmp = cur.right;       //找到左树最右节点或者右树最左节点来作为删除节点的值,然后操作删除左树最右节点或者右树最左节点。一般以右树最左节点来计算TreeNode tmpParent = cur;while (tmp.left!=null){tmpParent = tmp;tmp = tmp.left;             //找到右树最左节点后,剩下的操作就是将该节点值赋给删除的节点,然后操作删除右树的最左节点}cur.val = tmp.val;if (tmpParent.right == tmp){tmpParent.right = tmp.right;              //一开始的tmp就已经是右树最左端了!!!}else {tmpParent.left = tmp.right;                 //非一开始的tmp就已经是右树最左端了!!!}}}}

二叉搜索树【Java数据结构】相关推荐

  1. 《LeetCode力扣练习》第96题 不同的二叉搜索树 Java

    <LeetCode力扣练习>第96题 不同的二叉搜索树 Java 一.资源 题目: 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回 ...

  2. Leetcode--96. 不同的二叉搜索树(java)

    给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1         3   ...

  3. 使用C++实现二叉搜索树的数据结构

    需要注意的地方: ①二叉搜索树删除一个指定结点R,若R为叶子结点,则将R的父结点中指向R的指针改为指向nullptr:若R的左右子结点一个为空,一个非空,则将R的父结点中指向R的指针改为指向R的非空子 ...

  4. 二叉搜索树 【数据结构】

    二叉搜索树 概念 特点 基本操作 1.插入元素 2.查找元素 3.删除元素 概念 二叉搜索树是一种特殊的二叉树 特点 左子树中的值都小于根节点,右子树中的值都大于根节点 故:中序遍历结果就会得到一个有 ...

  5. java 二叉查找树_如何在Java中实现二叉搜索树( binary search tree)?

    二叉搜索树或BST是一种流行的数据结构,用于保持元素的顺序.二叉搜索树是二叉树,其中左子节点的值小于或等于父节点,右子节点的值大于或等于父节点.由于它是二叉树,它只能有0,1或2个子节点.二叉搜索树之 ...

  6. 【算法】有序链表转换二叉搜索树和从中序与后序遍历序列构造二叉树Java解答参考

    三道算法题 1.有序链表转换二叉搜索树 Java代码参考 2.从中序与后序遍历序列构造二叉树 Java代码参考 3.移除元素 Java代码参考 1.有序链表转换二叉搜索树 给定一个单链表,其中的元素按 ...

  7. 剑指offer | 面试题54:二叉搜索树的第k大节点

    转载本文章请标明作者和出处 本文出自<Darwin的程序空间> 本文题目和部分解题思路来源自<剑指offer>第二版 开始行动,你已经成功一半了,献给正在奋斗的我们 题目 给定 ...

  8. 二叉搜索树简介和部分题目

    引言 二叉搜索树是一个有序树,遵循以下规则: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉 ...

  9. 有序链表转换二叉搜索树(LeetCode)

    将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0, ...

  10. c++实现二叉搜索树

    自己实现了一下二叉搜索树的数据结构.记录一下: #include <iostream>using namespace std;struct TreeNode{int val;TreeNod ...

最新文章

  1. 2017年12月英语四级翻译预测
  2. go语言json解析的坑 注意事项
  3. 第二十二章 面向对象
  4. shared_ptr简介以及常见问题
  5. 前端学习(2325):angular之添加新组件
  6. Python reload() 函数
  7. C++编程(一):匈牙利命名法
  8. php是走什么协议,TCP是什么协议
  9. 《Spark The Definitive Guide》Chapter 6:处理不同类型的数据
  10. PCA(Principal Component Analysis)原理简单分析
  11. (135)FPGA面试题-介绍FPGA的速度等级与温度等级
  12. 【医疗影像处理】去除医疗影像中背景的影响2D/3D【numpy-code】
  13. android10LTE,Jelly 2:全球最小的Android 10 4G智能手机
  14. python情感分析词典_基于情感词典的文本情感分析
  15. MySQL的存储函数与存储过程的区别
  16. Stm32串口通信基础实验
  17. 抽奖活动软件 html,webAPP最常用的活动促销案例:大转盘H5抽奖特效
  18. 用JS代码输出101-200之间的素数
  19. python scrapy框架 抓取的图片路径打不开图片_Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码...
  20. HTML基础选择器之属性选择器的基本介绍

热门文章

  1. 自定义Camera系列之:TextureView + Camera
  2. 丘仕达工作前给大家的礼物(转)
  3. MySQL自带数据库
  4. 【调剂】江西科技师范大学电子科学与技术接收调剂研究生
  5. 奖券数目c语言答案,2015 年蓝桥杯 C 语言 B 组省赛第 1 题: 奖券数目 (四种解法 + 详细分析)...
  6. 物理真机上LUKS结合TPM的测试 —— 使用自己生成的密钥(问题版)
  7. 贾跃亭创办的FF又有新动作:国内成立新公司
  8. 最佳iOS设备管理器imazing 2.16.9官网Mac/Windows下载电脑版怎么下载安装
  9. java页面字体设置颜色_java 设置字体颜色字体 窗体设置图片背景
  10. sources和binaries文件区别