16、数据结构与算法-树结构-二叉排序树-笔记整理

为什么要用二叉排序树

使用数组

查找快,可以使用二分查找;
插入元素需要整体移动,速度慢

使用链表

无论是否有序查找都慢
添加数据快,不需要整体移动

使用二叉排序树

查找快,类似于二分查找
添加快,类似于链表

二叉排序树简介

特点:任何一个节点它的左子结点小于等于当前节点,右子节点大于等于当前节点
举例,对于数据(7,3,10,12,5,1,9)对于的二叉树为:
*

二叉排序树创建与遍历

创建流程:
1、 如果传入的节点小与当前节点,并且当前节点的左子结点为空则赋值给当前节点的左子结点,否者向左递归;
2、 如果传入的节点大于当前节点,并且当前节点的右子节点为空则赋值给当前节点的右子节点,否者向右递归;

遍历流程:
1、 使用中序遍历;

代码实现
public class BinarySortTreeDemo {
   
     

    public static void main(String[] args) {
   
     
        int[] arr = {
   
     7, 3, 10, 12, 5, 1, 9, 2};
        BinarySortTree binarySortTree = new BinarySortTree();
        //循环的添加结点到二叉排序树
        for (int i = 0; i < arr.length; i++) {
   
     
            binarySortTree.add(new Node(arr[i]));
        }
        //中序遍历二叉排序树
        System.out.println("中序遍历二叉排序树~");
        binarySortTree.infixOrder(); // 1, 3, 5, 7, 9, 10, 12
    }

}

//创建二叉排序树
class BinarySortTree {
   
     
    private Node root;

    public Node getRoot() {
   
     
        return root;
    }

    //添加结点的方法
    public void add(Node node) {
   
     
        if (root == null) {
   
     
            root = node;//如果root为空则直接让root指向node
        } else {
   
     
            root.add(node);
        }
    }

    //中序遍历
    public void infixOrder() {
   
     
        if (root != null) {
   
     
            root.infixOrder();
        } else {
   
     
            System.out.println("二叉排序树为空,不能遍历");
        }
    }
}

//创建Node结点
class Node {
   
     
    int value;
    Node left;
    Node right;

    public Node(int value) {
   
     
        this.value = value;
    }

    @Override
    public String toString() {
   
     
        return "Node [value=" + value + "]";
    }

    //添加结点的方法
    //递归的形式添加结点,注意需要满足二叉排序树的要求
    public void add(Node node) {
   
     
        if (node == null) {
   
     
            return;
        }
        //判断传入的结点的值,和当前子树的根结点的值关系
        if (node.value < this.value) {
   
     
            //如果当前结点左子结点为null
            if (this.left == null) {
   
     
                this.left = node;
            } else {
   
     
                //递归的向左子树添加
                this.left.add(node);
            }
        } else {
   
      //添加的结点的值大于 当前结点的值
            if (this.right == null) {
   
     
                this.right = node;
            } else {
   
     
                //递归的向右子树添加
                this.right.add(node);
            }

        }
    }

    //中序遍历
    public void infixOrder() {
   
     
        if (this.left != null) {
   
     
            this.left.infixOrder();
        }
        System.out.println(this);
        if (this.right != null) {
   
     
            this.right.infixOrder();
        }
    }

}

删除流程:
删除流程较为复杂,这里大概说下思路:
1、 如果要删除的节点无子节点,可以直接删除,让其父节点将该子节点制空即可;
*
2、 如果要删除的节点只有一个节点,直接将要删除节点的父节点指向要删除节点的子节点;
*
3、 如果要删除两个子节点的节点思路如下:;
1)找到要删除的节点targetNode
2)从targetNode找到右子树的最小节点,临时保存在temp里面
3)将该节点替换为要删除的节点,targetNode.value=temp

*

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: