二叉查找树中节点的包含,插入,删除操作

二叉查找树

最近在看大话数据结构,遇到二叉查找树,原理上听起来比较简单,但是要实际写代码实现的时候感觉还是有点困难。

1. 二叉查找树的定义:

        一棵空数,或者是具有如下性质的二叉树:

        ①若左子树不空,则左子树上所有节点的值均小于它根节点上的值。

        ②若右子树不空,则右子树上所有节点的值均小于它根节点上的值。

        ③它的左右子树也分别为二叉查找树。

        特别注意:二叉查找树一定要满足左子树上的值全部比根节点小,右子树上的值全部比根节点大。

2.二叉查找树的包含:

        判断某个节点是否在二叉查找树上,原理实现应该是很容易,将目标值与根节点比较,大于根节点的值,则以根节点的右节点递归,小于根节点的值,则以根节点的左节点递归。相等的时候,则返回正确值。

代码实现:

public boolean contains(TreeNode t, int key){
        if(t == null){
            return false; 
        }
        if(t.val < key){
            return contains(t.right, key);
        }if(t.val > key){
            return contains(t.left, key);
        }else{
            return true;
        }
    }

3.二叉查找树的最大,最小值:

        二叉查找树的最大最小值应该是比较容易实现的,根据定义,最左端的叶子节点上的值即为最小值,最右端的叶子节点上的值即为最大值。(最小值将right改为left即可)

代码实现:

非递归实现:

public TreeNode findMax(TreeNode t){
        if(t == null){
            return null;
        }
        while(t.right != null){
            t = t.right;
        }
        return t;
    }

递归实现:

public TreeNode findMax(TreeNode t){
        if(t == null){
            return null;
        }
        if(t.right == null){
            return t;
        }
        return findMax(t.right);
    }

4.二叉查找树的插入:

可以想象,插入一个节点,即是在某个节点上面多加一条分支,但是如果树中某个节点的值与其相等的话,则不做任何操作。

public TreeNode insert(TreeNode t, int key){
        if(t == null){
            return new TreeNode(key);
        }
        if(t.val < key){
            t.right = insert(t.right, key);
        }if(t.val > key){
            t.left = insert(t.left, key);
        }else{};

        return t;
    }

5.二叉查找树的删除:

删除是二叉查找树中最为复杂的一个操作,可以分成三种情况来考虑:

①若是叶子节点的话,只需要将其赋值为空即可;

②若仅包含左节点或者右节点,则将其左节点或者右节点的值赋给其本身,将左右节点赋值为空;

③若既包含左节点,也包含右节点,则可以通过中序遍历将其前驱(或后继)节点的值赋给其本身,将前驱(后继)

    节点删除。

代码实现:

实现一:

public TreeNode remove(TreeNode t, int key){
        if(t == null){
            return null;
        }
        if(t.val == key){
            if(t.left != null && t.right == null){
                t = t.left;
            }else if(t.right != null && t.left == null){
                t = t.right;
            }else if(t.right != null && t.left != null){
                t.val = findMax(t.left).val;
                remove(t.left, t.val);
            }else{
                t = null;
            }
        }else if(t.val < key){
            t.right = remove(t.right, key);
        }else {
            t.left = remove(t.left, key);
        }
        return t;
    }

实现二:

public TreeNode remove1(TreeNode t, int key){
        if(t == null){
            return t;
        }
        if(t.val < key){
            t.right = remove1(t.right, key);
        }else if(t.val > key){
            t.left = remove1(t.left, key);
        }else if(t.left != null && t.right != null){
            t.val = findMin(t.right).val;
            t.right = remove1(t.right, t.val);
        }else{
            t = (t.left != null) ? t.left : t.right;
        }
        return t;
    }

实现二中findMin方法为前面二叉查找树的最小值的方法。

实现一和二的区别在于若左右节点均不为空的时候,一个使用的是前驱,一个使用的是后继来代替。

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/xiaobangdesk/article/details/79658522
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞