数据结构与算法入门——二叉树之二叉排序树

二叉排序树概述

  • 为什么会有二叉排序树
    之前我们学过顺序存储的二叉树和链式存储的二叉树,他俩都面临着结点的查询比较慢的缺点,于是便有了二叉排序树
  • 什么是二叉排序树
    二叉排序树,也叫二叉查找树,二叉搜索树,顾名思义查找结点便是十分方便。对于二叉树中任何一个非叶子结点,要求左子结点比当前结点值小,右子结点比当前结点大,因此针对于这种排列方式,要求该树不能有相同的结点

结点的增删查

//结点类
public class BinarySortTreeNode {
    int value;
    BinarySortTreeNode left;
    BinarySortTreeNode right;

    public BinarySortTreeNode(int value) {
        this.value = value;
    }
    public void middleShow(){
        if (left != null){
            left.middleShow();
        }
        System.out.println(this.value);
        if (right != null){
            right.middleShow();
        }
    }

    /**
     * 添加结点的方法
     * @param node
     */
    public void add(BinarySortTreeNode node) {
        //如果传入的节点为空,则直接返回
        if (node == null){
            return;
        }
        //如果不为空,咋将当前结点与传入结点的值作比较
        if (node.value<this.value){
            //如果传入结点比当前结点小,则作为当前节点的左子结点
            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 BinarySortTreeNode search(int value) {
        //首先判断根节点
        if (this.value == value){
            return this;
        }else if (this.value>value){
            if (left == null){
                return null;
            }
               return left.search(value);
        }else {
            if (right == null){
                return null;
            }
               return right.search(value);
        }
    }

    public BinarySortTreeNode searchParent(int value) {
        if((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)){
            return this;
        }else {
            if (this.value >value && this.left != null){
               return this.left.searchParent(value);
            }else if (this.value < value && this.right != null){
                return this.right.searchParent(value);
            }
            return null;
        }
    }
}
//树类
public class BinarySortTree {
    BinarySortTreeNode root;

    //添加节点方法
    public void add(BinarySortTreeNode node){
        if (root == null){
            root = node;
        }else {
            root.add(node);
        }
    }

    //打印树
    public void show() {
        root.middleShow();
    }
    //查找结点
    public BinarySortTreeNode search(int value){
        //如果根结点为空,则直接false
        if (root == null){
            return null;
        }else {
           return root.search(value);
        }

    }
    //查找父结点
    public BinarySortTreeNode searchParent(int value){
        //如果根结点为空,则直接false
        if (root == null){
            return null;
        }else {
            if (root.value == value){
                return null;
            }
            return root.searchParent(value);
        }

    }
    //删除结点
    public void delete(int value){
           if (root == null){
               return;
           }else {
               //如果根结点不为空,则找到要删除的结点
               BinarySortTreeNode node = search(value);
               if (node == null){
                   return;
               }
               //找到他的父亲结点
                BinarySortTreeNode parent = searchParent(value);
               //如果要删除的是叶子结点
               if (node.left == null&& node.right == null){
                   if (parent.left != null && parent.left.value == value){
                       //如果该父结点的左结点不为空并且结点值相等,则左结点为空
                       parent.left = null;
                   }
                   if (parent.right != null&& parent.right.value == value){
                       //如果该父结点的右结点不为空并且结点值相等,则右结点为空
                       parent.right = null;
                   }

               }else if (node.left != null && node.right != null){
                   //如果要删除的是有左右两个子节点的父结点
                   //删除右子树中值最小的结点,并将其值返回
                   int min = deleteMin(node.right);
                   //替换目标节点的值
                   node.value = min;
               }else{
                  //如果删除的是只有一个子结点的父结点
                   if (node.left != null) {
                       //如果是只有一个左子结点
                       if (parent.left != null &&parent.left.value == value){
                           //如果要删除的该结点是其父结点的左子结点,则把该结点的左子结点作为该结点父结点的左子结点
                           parent.left = node.left;
                       }else {
                           //如果要删除的该结点是其父结点的右子结点,则把该结点的左子结点作为该结点父结点的右子结点
                           parent.right = node.left;
                       }
                   }else {
                       //如果是只有一个右子结点
                       if (parent.left != null && parent.left.value == value){
                           //如果要删除的该结点是其父结点的左子结点,则把该结点的右结点作为该结点父结点的左子结点
                           parent.left = node.right;
                       }else {
                           //如果要删除的该结点是其父结点的右子结点,则把该结点的右结点作为该结点父结点的右子结点
                           parent.right = node.right;
                       }
                   }
               }
           }
    }

    //删除并返回右子树中的最小结点
    private int deleteMin(BinarySortTreeNode node) {
        //获取传入的结点
        BinarySortTreeNode target = node;
        //递归向左找,直到找到最小的那个值
        while (target.left != null){
            target = target.left;
        }
        //找到后删除该最小结点,并返回其值
        delete(target.value);
        return target.value;
    }
}
	//测试类
public class TestBinarySortTree {
    public static void main(String[] args) {
        int[] arr = new int[]{5,7,9,1,6,3,4};
        BinarySortTree tree = new BinarySortTree();
        for (int i : arr) {
            tree.add(new BinarySortTreeNode(i));
        }
        tree.show();
        System.out.println("=======================");
        System.out.println(tree.search(5).value);
        System.out.println(tree.search(10));
        System.out.println("=======================");
        tree.delete(5);
        tree.show();
    }
}
发布了23 篇原创文章 · 获赞 5 · 访问量 1142

猜你喜欢

转载自blog.csdn.net/qq_40181435/article/details/104898620