Java超详细讲解排序二叉树

目录
  • 排序二叉树概念
  • 排序二叉树类的定义
  • 添加节点
  • 中序遍历
  • 查找节点
  • 查找某一节点的父节点
  • 删除节点

排序二叉树概念

  • 二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。是数据结构中的一类。
  • 对于二叉排序树的任何一个非叶子节点, 要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。
  • 对二叉排序树进行中序遍历,结果就是按从小到大排序的。

排序二叉树类的定义

public class binarySortTree {
    class Node{
        int value;
        Node left;
        Node right;
        public Node(int value){
            this.value = value;
        }
        public void display(){
            System.out.print(this.value + " ");
        }
    }
    Node root;
}

添加节点

排序二叉树添加节点的十分简单,无论使用递归还是循环,思路都一样,这里我用递归的方式讲解。

  1. 每次添加一个节点时,判断value(添加节点的值)与root的值的大小关系: 若root.value < value, 说明该节点应该添加在root的右子树上。如果右子树为空,直接添加:root.right = new Node(value);如果右子树不为空,那么递归进右子树(令root.right为root)。
  2. root.value >= value, 说明该节点应该添加在root的左子树上。如果左子树为空,直接添加:root.left = new Node(value);如果左子树不为空,那么递归进右子树(令root.left为root)。

代码如下:

//添加节点
	//此方法可以类内部方法的调用
    private void add(Node root,int value){
        //添加节点的值大于根节点的值,该节点添加到根节点的右子树上
        if(value > root.value){
            //根节点的右子树为空,直接添加
            if(root.right == null){
                root.right = new Node(value);
            }
            //根节点右子树不为空,递归往右子树插
            else{
                add(root.right,value);
            }
        }
        //添加节点的值小于或者等于根节点的值,该节点应该添加到左子树
        else{
            //左子树为空,直接添加
            if(root.left == null){
                root.left = new Node(value);
            }
            //左子树不为空,递归往左子树添加
            else{
                add(root.left, value);
            }
        }
    }
    //此方法在类内部和类外部都可以调用
    public void add(int value){
        //当前树为空树
        if(root == null){
            root = new Node(value);
            return;
        }
        add(root, value);
    }

中序遍历

因为二叉排序树中序遍历的结果就是排序好的,所以这里只提供中序遍历。

代码如下:

//中序遍历树
    private  void inPrevOrder(Node root){
        if(root == null) return;
        inPrevOrder(root.left);
        root.display();
        inPrevOrder(root.right);
    }
    public void inPrevOrder(){
        System.out.print("中序遍历:");
        inPrevOrder(root);
    }

查找节点

该方法是查找value在二叉树中对应的位置,是为删除节点提供的方法。

/**
     * 通过value查找二叉树中的节点
     * @param root 被查找树的根节点
     * @param value 要查找的值
     * @return 返回查找到的节点
     */
    private Node searchNode(Node root, int value){
        //被查找树为null,要查找节点不存在
        if(root == null)
            return null;
        //找到了,返回节点
        else if(root.value == value){
            return root;
        }
        //该节点不是要查找节点,继续查找
        else{
            //该节点的值大于value,往该节点的左子树递归查找
            if(root.value > value){
                return searchNode(root.left, value);
            }
            //该节点的值小于value,往该节点的右子树递归查找
            else{
                return searchNode(root.right, value);
            }
        }
    }

查找某一节点的父节点

该方法是查找二叉树中一个节点的父节点,也是为删除节点提供的方法。

 /**
     * 查找某节点的父节点,并返回
     * @param root 被查找树的根节点
     * @param node 要查找的节点
     * @return 返回被查找节点的父节点
     */
    private Node searchParentNode(Node root, Node node){
        //被查找树为null或者根节点就是要查找的节点,那么要查找节点的父节点不存在
        if(root == null || root == node){
            return null;
        }
        else if(root.left != null && root.left == node || root.right != null && root.right == node){
            return root;
        }
        else{
            if(root.value > node.value){
                return searchParentNode(root.left, node);
            }
            else{
                return searchParentNode(root.right, node);
            }
        }
    }

删除节点

删除节点是排序二叉树中最麻烦的方法,因为它有很多种情况。

方法如下:

第一种情况:删除的节点是叶子节点
(1)需求先去找到要删除的结点targetNode

(2)找到targetNode的父结点parent

(3)确定targetNode是parent的左子结点还是右子结点
   3.1如果targetNode是parent的左子结点:parent.left = null;
   3.2如果targetNode是parent的右子结点:parent.right = null;
   第二种情况:删除只有一颗子树的节点
(1)需求先去找到要删除的结点targetNode

(2)找到targetNode的父结点parent

(3)确定targetNode的子结点是左子结点还是右子结点

(4)确定targetNode是parent的左子结点还是右子结点

(5)如果targetNode有左子结点
   5.1如果targetNode是parent的左子结点parent.left = targetNode.left;
   5.2如果targetNode是parent的右子结点parent.right = targetNode.left;
(6)如果targetNode有右子结点
   6.1如果targetNode是 parent 的左子结点parent.left = targetNode.right;
   6.2如果targetNode是parent 的右子结点parent.right = targetNode.right
    第三种情况:删除的节点有左右两个子树
(1)需求先去找到要删除的结点targetNode

(2)在右子树找到最小的节点,用一个temp保存这个节点的值,然后删除这个最小节点(该最小节点一定是满足第一种情况的)

(3)targetNode.value = temp

除了以上情况,还要考虑要删除的节点就是根节点的情况(此时它的父节点为null),下面会在代码中展示,代码如下:

public void remove(int vlaue){
        //找到要删除的节点
        Node targetNode = searchNode(root,vlaue);
        //要删除节点不存在
        if(targetNode == null) return;
        //找到要删除节点的父节点
        Node targetNodeParent = searchParentNode(root,targetNode);
        //要删除节点为叶子节点
        if(targetNode.left == null && targetNode.right == null){
            //要删除的节点就是根节点
            if(targetNodeParent == null){
              root = null;
            }
            else{
                //要删除节点是其父节点的左节点
                if(targetNodeParent.left == targetNode){
                    targetNodeParent.left = null;
                }
                else{
                    targetNodeParent.right = null;
                }
            }
        }
        //要删除节点只有一个左子树
        else if(targetNode.left != null && targetNode.right == null){
            //要删除的节点就是根节点
            if(targetNodeParent == null) {
                root = root.left;
            }
            //要删除节点是其父节点的左节点
            else if(targetNodeParent.left != null && targetNodeParent.left.value == targetNode.value){
                targetNodeParent.left = targetNode.left;
            }
            //要删除节点是其父节点的右节点
            else{
                targetNodeParent.right = targetNode.left;
            }
        }
        //要删除节点只有一个右子树
        else if(targetNode.right != null && targetNode.left == null){
            //要删除的节点就是根节点
            if(targetNodeParent == null) {
                root = root.right;
                return;
            }
            //要删除节点是其父节点的左节点
            else if(targetNodeParent.left != null && targetNodeParent.left.value == targetNode.value){
                targetNodeParent.left = targetNode.right;
            }
            //要删除节点是其父节点的右节点
            else{
                targetNodeParent.right = targetNode.right;
            }
        }
        //要删除节点右左右都有节点
        else{
            //找到右子树最小的节点
            Node minNode = targetNode.right;
            while(minNode.left != null){
                minNode = minNode.left;
            }
            int temp = minNode.value;
            //找到右子树上最小节点的父节点
            Node minNodeParent = searchParentNode(targetNode.right,minNode);
            //右子树根节点就是最小节点
            if(minNodeParent == null){
                targetNode.right = minNode.right;
            }
            else{
                //要删除节点是其父节点的左节点
                minNodeParent.left = minNode.right;
            }
            targetNode.value = temp;
        }
    }

到此这篇关于Java超详细讲解排序二叉树的文章就介绍到这了,更多相关Java排序二叉树内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java的二叉树排序以及遍历文件展示文本格式的文件树

    Java二叉树排序算法 排序二叉树的描述也是一个递归的描述, 所以排序二叉树的构造自然也用递归的: 排序二叉树的3个特征: 1:当前node的所有左孩子的值都小于当前node的值: 2:当前node的所有右孩子的值都大于当前node的值: 3:孩子节点也满足以上两点 package test.sort; public class BinaryNode { private int value;//current value private BinaryNode lChild;//left chil

  • java 实现最小二叉树堆排序的实例

    java 实现最小二叉堆排序的实例 写在前面: 一觉醒来,我就突然有灵感了...... 最小二叉堆定义: 二叉堆是完全二元树或者是近似完全二元树,最小二叉堆是父结点的键值总是小于或等于任何一个子节点的键值的堆堆. 存储: 二叉堆一般用数组来表示. 根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2: 位置k的叶子的父节点位置为(k-1)/2: 实现: /** * @description 元素添加到末尾,和它的父节点比,如果比它小就交换 * @param array * *

  • Java超详细讲解排序二叉树

    目录 排序二叉树概念 排序二叉树类的定义 添加节点 中序遍历 查找节点 查找某一节点的父节点 删除节点 排序二叉树概念 二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树.是数据结构中的一类. 对于二叉排序树的任何一个非叶子节点, 要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大. 对二叉排序树进行中序遍历,结果就是按从小到大排序的. 排序二叉树类的定义 public class binarySortTree {

  • Java 超详细讲解十大排序算法面试无忧

    目录 排序算法的稳定性: 一.选择排序 二.冒泡排序 三.插入排序 四.希尔排序 五.堆排序 六.归并排序 七.快速排序 八.鸽巢排序 九.计数排序 十.基数排序 排序算法的稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,如果排序以后,保证这些记录的相对次序保持不变,即在原序列中,a[i]=a[j],且 a[i] 在 a[j] 之前,排序后保证 a[i] 仍在 a[j] 之前,则称这种排序算法是稳定的:否则称为不稳定的. 一.选择排序 每次从待排序的元素中选择最小的元素,依次

  • C语言超详细讲解排序算法上篇

    目录 1.直接插入排序 2.希尔排序(缩小增量排序) 3.直接选择排序 4.堆排序 进入正式内容之前,我们先了解下初阶常见的排序分类 :我们今天讲前四个! 1.直接插入排序 基本思想:当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排 序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移! 直接插入排序的特性总结: 1. 元素集

  • Java 超详细讲解数据结构中的堆的应用

    目录 一.堆的创建 1.向下调整(以小堆为例) 2.创建堆 3.创建堆的时间复杂度 二.堆的插入和删除 1.堆的插入 2.堆的删除 三.堆的应用 1.堆排序 2.top-k问题 [求最小的K个数] 四.常用接口的介绍 1.PriorityQueue的特性 2.优先级队列的构造 一.堆的创建 1.向下调整(以小堆为例) 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子) 如果parent的左孩子存在,即:child < size,

  • Java 超详细讲解抽象类与接口的使用

    目录 一.抽象类 1.抽象类的语法 2.抽象类的特性 3.抽象类的作用 二.接口 1.接口的概念 2.接口使用 3.接口特性 4.实现多个接口 5.接口间的继承 6.常用的接口 (1)Comparable接口 (2)Cloneable接口 三.Object类 一.抽象类 在Java中,如果一个类被abstract修饰称为抽象类,抽象类中被abstract修饰的方法称为抽象方法,抽象方法不用给出方法体. 1.抽象类的语法 //抽象类:被abstract修饰的类 public abstract cl

  • Java 超详细讲解数据结构的应用

    目录 一.bfs 二.双端队列 三.算法题 1.kotori和迷宫 2.小红找红点 3.小红玩数组  一.bfs bfs(广度优先搜索),类似二叉树的层序遍历,利用队列完成.一般用于求最短路. 图的最短路问题: 给定一个无向图,每条边的长度都是1.求1号点到x号点的最短距离. 顶点数n  边数为m q次询问  输入x 输出1到x的最短距离. 若1号点到x不连通,则输出-1 二.双端队列 双端队列的应用(区间翻转): 对于长度为n的数组,给定一个长度为m的区间,区间初始位置为a[1]到a[m].

  • Java 超详细讲解数据结构中的堆的应用

    目录 一.堆的创建 1.向下调整(以小堆为例) 2.创建堆 3.创建堆的时间复杂度 二.堆的插入和删除 1.堆的插入 2.堆的删除 三.堆的应用 1.堆排序 2.top-k问题(求最小的K个数) 四.常用接口的介绍 1.PriorityQueue的特性 2.优先级队列的构造 一.堆的创建 1.向下调整(以小堆为例) 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子) 如果parent的左孩子存在,即:child < size, 进

  • Java 超详细讲解设计模式之中的抽象工厂模式

    目录 抽象工厂模式 1.什么是抽象工厂 2.抽象工厂模式的优缺点 3.抽象工厂模式的结构与实现 4.抽象工厂方法模式代码实现 5.抽象工厂模式的应用场景 6.抽象工厂模式的扩展 抽象工厂模式 前面文章介绍的工厂方法模式中考虑的是一类产品的生产,比如案例中的百事可乐工厂只能生产百事可乐,可口可乐工厂只能生产可口可乐,也就是说:工厂方法模式只考虑生产同等级的产品. 1.什么是抽象工厂 在现实生活中许多工厂是综合型的工厂,能生产多种类)的产品,就拿案例里面的可乐来说,在节日的时候可能会有圣诞版的可乐,

  • Java 超详细讲解IO操作字节流与字符流

    目录 IO操作 字节流 FileInputStream FileOutputStream 字节流读写案例 字符流 FileReader FileWriter 字节流与字符流的区别 IO操作 字节流 java.io.InputStream 输入流,主要是用来读取文件内容的. java.io.OutputStream 输出流,主要是用来将内容字节写入文件的. FileInputStream 该流用于从文件读取数据,它的对象可以用关键字 new 来创建. 有多种构造方法可用来创建对象. 可以使用字符串

  • Java 超详细讲解设计模式之中的建造者模式

    目录 1.什么是建造者模式? 2.建造者模式的定义 3.建造者模式的优缺点 4.建造者模式的结构 5.建造者模式代码演示 6.建造者模式的应用场景 7.建造者模式和工厂模式的区别 1.什么是建造者模式? 我们知道在软件开发过程中有时需要创建一个很复杂的对象,通常由多个子部件按一定的步骤组合而成. 例如,比如我们在自己在组装一台计算机的时候,需要有 CPU.主板.内存.硬盘.显卡.机箱.显示器.键盘.鼠标等部件组装而成的.比如学校需要采购100台计算机,学校不可能自己把零件买过来自己组装,肯定是告

随机推荐