二叉搜索树

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树

/**
 * 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)
 */
public class BinarySearchTreeTest {
    public static void main(String[] args) {

    }

    static class TNode {
        int value;
        TNode leftChild;
        TNode rightChild;
        public TNode(int value) {
            this.value = value;
        }
    }

    private static TNode find(TNode root,int value){
        TNode node = root;
        while (node != null && node.value != value){
            if (value < node.value)
                node = node.leftChild;
            else
                node = node.rightChild;
        }
        return node; // 找到活等于空
    }

    /**
     * 递归查找
     */
    private static TNode find2(TNode root,int value){
        if (root == null){
            return null;
        }
        if (root.value == value){
            return root;
        }else if (value < root.value){
            return find2(root.leftChild,value);
        }else
            return find2(root.rightChild,value);
    }

    /**
     * 插入会在叶子节点处插入
     */
    private static void insert(TNode root,int value){
        if (root == null){
            root = new TNode(value);
            return;
        }
        TNode pre = root;
        TNode cur = root;
        boolean isLeft = true;
        while (cur != null && cur.value != value){
            pre = cur;
            if (value < cur.value){
                cur = cur.leftChild;
                isLeft = true;
            } else{
                cur = cur.rightChild;
                isLeft = false;
            }

        }
        if (cur != null)
            return; // cur.value == value 的情况不进行出入
        else if (isLeft){
            pre.leftChild = new TNode(value);
            return;
        }else {
            pre.rightChild = new TNode(value);
            return;
        }
    }

    private void inOrder(TNode root){
        if (root == null)
            return;
        inOrder(root.leftChild);
        System.out.println(root.value);
        inOrder(root.rightChild);

    }

    private static void insert2(TNode root,int value){
        if (root == null){
            root = new TNode(value);
            return;
        }
        while (root.value != value){
            if (value < root.value)
                insert2(root.leftChild,value);
            else
                insert2(root.rightChild,value);
        }
    }

    /**
     * 在二叉搜索树中删除节点操作较复杂,可分为三种情况
     * 1.没有子树
     * 2.一个子树
     * 3.有左右子树 (用要删除节点的右子树里最小的节点的值替换要删除节点的值,
     * 然后,再把那个最小节点删除。注意:右子树值最小节点一定不不含左子树,要不它就不是最小的了)
     */
    public boolean delete(TNode root,int value){
        TNode pre = root;
        TNode cur = root;
        boolean isLeft = true;
        while (cur != null && cur.value != value){
            pre = cur;
            if (value < cur.value){
                cur = cur.leftChild;
                isLeft = true;
            }else {
                cur = cur.rightChild;
                isLeft = false;
            }
        }

        if (cur == null){
            return false; // cur == null 说明没找到
        }

        // 找到了,就开始删了
        if (cur.leftChild == null && cur.rightChild == null){
            // 1. 叶子节点,没有左右子树为叶子节点
            if (cur == root)
                root = null;
            else if (isLeft)
                pre.leftChild = null;
            else
                pre.rightChild = null;

        }else if (cur.leftChild == null){
            // 2. 只有一个右子树
            if (cur == root)
                root = root.rightChild;
            else if (isLeft)
                pre.leftChild = cur.rightChild;
            else
                pre.rightChild = cur.rightChild;

        } else if (cur.rightChild == null){
            // 2. 只有一个左子树
            if (cur == root)
                root = root.leftChild;
            else if (isLeft)
                pre.leftChild = cur.leftChild;
            else
                pre.rightChild = cur.leftChild;

        }else {
            // 3. 有左右子树
            cur.value = dirctPostNode(cur).value;
        }
        return true;
    }

    /**
     * 找到要删除节点的直接后继节点,并执行相应的操作
     * 找到其右子树中值最小的节点
     */
    private static TNode dirctPostNode(TNode del){
       TNode pre = null;
       TNode dirctPostNode = del;
       TNode cur = del.rightChild;
       while (cur != null){
           pre = dirctPostNode; // 移动pre 指针
           dirctPostNode = cur; // 移动直接后继指针
           cur = cur.leftChild;
       }

       if (dirctPostNode == del.rightChild){
           del.rightChild = null;
       }else {
           pre.leftChild = dirctPostNode.rightChild;
           dirctPostNode.rightChild = null;
       }
       return dirctPostNode;


    }

}

求二叉树的高度

private static int getTreeHeight(TNode root){
        if (root == null)
            return 0;
        int leftHeight = getTreeHeight(root.leftChild);
        int rightHeight = getTreeHeight(root.rightChild);
        return leftHeight > rightHeight ? leftHeight+1 : rightHeight + 1;
    }

二叉搜索树Java实现(查找、插入、删除、遍历) https://www.cnblogs.com/Michaelwjw/p/6384428.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值