数据结构与算法(二十七)二叉排序树

二叉排序树介绍

二叉排序树:BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。
特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点
二叉排序树创建和遍历

一个数组创建成对应的二叉排序树,并使用中序遍历二叉排序树,比如: 数组为 Array(7, 3, 10, 12, 5, 1, 9) , 创建成对应的二叉排序树为 :
image.png

二叉排序树的删除

二叉排序树的删除情况比较复杂,有下面三种情况需要考虑

删除叶子节点 (比如:2, 5, 9, 12)
删除只有一颗子树的节点 (比如:1)
删除有两颗子树的节点. (比如:7, 3,10 )

image.png

代码实现

节点对象
class Node{

     int value;
     Node left;
     Node right;

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


    /**
     * 根据value查询节点的父节点
     * @param value
     * @return
     */
    public Node searchParent(int value){
         if ((this.left!=null&& this.left.value == value)||
                 (this.right!=null&&this.right.value==value)){
             return this;
         }else {
             if (value<this.value&&this.left!=null){
                 return this.left.searchParent(value);
             }else if (value>=this.value&&this.right!=null){
                 return this.right.searchParent(value);
             }else {
                 return null;
             }
         }

      }

    /**
     *  根据value查找节点
     * @param value
     * @return
     */
     public Node search(int value){
         if (value == this.value){
             return this;
         }else if (value < this.value){
             if (this.left == null ){
                 return null;
             }
             return this.left.search(value);
         }else {
             if (this.right == null ){
                 return null;
             }
             return this.right.search(value);
         }
     }


    /**
     * 递归的形式添加节点
     * @param node
     */
     public void add(Node 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 void infixOrder(){
         if (this.left!=null){
             this.left.infixOrder();
         }
         System.out.println(this);
         if (this.right!=null){
             this.right.infixOrder();
         }
     }




    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }
}
二叉排序树
/**
 * 二叉排序树
 */
public class BinarySortTree {


    private Node root;

    public Node getRoot() {
        return root;
    }

    /**
     *  查询
     * @param value
     * @return
     */
    public Node search(int value){
        if (root == null){
            return null;
        }
        return root.search(value);
    }

    /**
     * 根据value 查询节点的父节点
     * @param value
     * @return
     */
    public Node searchParent(int value){

        if (root == null ){
            return null;
        }
        return  root.searchParent(value);
    }

    /**
     * 增加节点
     * @param value
     */
    public void add(int value){
        Node node = new Node(value);
        if (root == null){
            root=node;
            return;
        }
        root.add(node);
    }

    /**
     * 中序遍历
     */
    public void infixOrder(){
        if (root != null){
            root.infixOrder();
        }
    }

    /**
     * 删除node为根节点的二叉排序树的最小节点
     * @param node
     * @return
     */
    public int delRightTreeMin(Node node){
        Node target=node;
        while (target.left!=null){
            target=target.left;
        }
        delNode(target.value);
        return target.value;
    }


    /**
     * 删除节点
     * @param value
     */
    public void delNode(int value){
        if (root == null){
            return;
        }
        Node targetNode = this.search(value);
        if (targetNode == null){
            return;
        }
        if (root.left == null && root.right == null){
            root=null;
            return;
        }
        Node parent = this.searchParent(value);

        if (targetNode.left == null && targetNode.right == null){

            if (parent.left!=null&&parent.left.value==value){
                parent.left=null;
            }else if (parent.right!=null&&parent.right.value==value){
                parent.right=null;
            }
        }else if (targetNode.left!=null&&targetNode.right!=null){
              int minVal=delRightTreeMin(targetNode.right);
              targetNode.value=minVal;
        }else {
            if (targetNode.left!=null){
                if (parent!=null) {
                    if (parent.left.value == value){
                        parent.left=targetNode.left;
                    }else {
                        parent.right=targetNode.left;
                    }
                }else {
                    root=targetNode.left;
                }
            }else {
                if (parent !=null){
                    if (parent.left.value==value){
                        parent.left=targetNode.right;
                    }else {
                        parent.right=targetNode.right;
                    }
                }else {
                    root=targetNode.right;
                }
            }
        }

    }

    public static void main(String[] args) {
        int[] arr = { 10, 11, 7, 6, 8, 9 };
        BinarySortTree binarySortTree = new BinarySortTree();
        for (int i = 0; i <arr.length; i++) {
            binarySortTree.add(arr[i]);
        }
        binarySortTree.infixOrder();


    }

}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.fengpt.cn/archives/数据结构与算法二十七二叉排序树