二叉排序树的操作

删除结点是比较麻烦的,这里简要介绍一下如何删除结点
1.待删除的结点是叶子结点,这种很简单,直接令指向该结点的指针指向null即可
2.待删除的结点只有左子树,这种也比较好操作,令指向该结点的指针指向该结点的左子树即可
3.待删除的结点只有右子树,这种同上操作,令指向该结点的指针指向该结点的右子树即可
4.待删除的结点的左子树和右子树均不为空,这种情况下,我们可以将删除操作进行转换,转换为上述第2或3种情况。
两种解决方式:
√左子树中找最大值,那么左子树中的左右结点都是小于该最大值的,用该最大值去替换待删除结点的值,此时再去删除左子树中最大结点的值就可以了。由于是左子树中最大结点,所以该结点的右子树必为空,是第2种情况。
√右子树中找最小值,那么右子树中的所有结点都是大于该值的,用该最小值去替换待删除结点的值,此时再去删除右子树中最小节点的值就可以了。此时的树仍满足二叉排序树。由于是右子树中最小的结点,所以该结点的左子树必为空,是第3中情况。

package dream.linearlist.tree;

/**
 * Created by Dream on 2018/3/13.
 */
class TreeNode{
    TreeNode left;
    TreeNode right;
    int val;
    public TreeNode(int val){
        this.val = val;
    }
}
public class BinarySearchTree {
    /**
     * 查找二叉树的非递归实现
     * @param root
     * @param elem
     * @return
     */
    public TreeNode Find(TreeNode root,int elem){
        while(root != null){
            if (elem > root.val)
                root = root.right;
            else if (elem < root.val)
                root = root.left;
            else
                return root;
        }
        return null;
    }
    /**
     * 查找二叉树的递归实现
     * @param root
     * @param elem
     * @return
     */
    public TreeNode FindRecursive(TreeNode root,int elem){
        if (root == null)
            return null;
        if (elem > root.val)
            return  FindRecursive(root.right,elem);
        else if(elem < root.val)
            return  FindRecursive(root.left,elem);
        else
            return root;
    }
    /**
     * 插入结点的非递归实现
     * @param root
     * @param elem
     */
    public void InsertNode(TreeNode root,int elem){
        if (root == null)
            return;
        TreeNode prev = null,curr = root;
        while(curr != null){
            if(elem > curr.val){
                prev = curr;
                curr = curr.right;
            }else if(elem < curr.val){
                prev = curr;
                curr = curr.left;
            }else{
                System.out.println("结点已存在!");
                return;
            }
        }
        if (elem > prev.val){
            prev.right = new TreeNode(elem);
        }else{
            prev.left = new TreeNode(elem);
        }
    }
    /**
     * 插入结点的递归实现
     * @param bst
     * @param elem
     * @return
     */
    public TreeNode InsertNodeRecursive(TreeNode bst,int elem){
        if (bst == null){
            bst = new TreeNode(elem);
        }
        if (elem > bst.val)
            bst.right = InsertNodeRecursive(bst.right,elem);
        else if(elem < bst.val)
            bst.left = InsertNodeRecursive(bst.left,elem);
        return bst;
    }
    /**
     * 删除结点:
     * @param root
     * @param elem
     * @return
     */
    public TreeNode deleteNode(TreeNode root,int elem){
        TreeNode temp = null;
        if (root == null)
            return null;
        else if (elem > root.val){
            root.right = deleteNode(root.right,elem);
        }else if(elem < root.val)
            root.left = deleteNode(root.left,elem);
        else{  //找到了该结点
            if (root.left != null && root.right != null){     //左右子树均不为空
                temp = FindMinNode(root);  //找到右子树中的最小值
                root.val = temp.val;       //将最小值赋给当前结点,然后删除右子树中的最小结点值(保证该结点是没有左孩子结点的)
                root.right = deleteNode(root.right,root.val);
            }else{     //左右子树至少有一为空
                if(root.left != null){
                    root = root.left;
                }else{
                    root = root.right;
                }
            }
        }
        return root;
    }
    /**
     * 寻找最小结点,也就是最左叶子结点
     * @param root
     * @return
     */
    public TreeNode FindMinNode(TreeNode root){
        TreeNode curr = root;
        while(curr != null && curr.left != null){
            curr = curr.left;
        }
        return curr;
    }
    /**
     * 寻找最大结点,也就是最右叶子结点
     * @param root
     * @return
     */
    public TreeNode FindMaxNode(TreeNode root){
        if (root == null)
            return null;
        else if (root.right == null)   //找到最大右结点并返回
            return root;
        else
            return FindMaxNode(root.right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值