Binary Search Tree二叉搜索树 Java实现

 
 

insert()方法。这是我一开始听完课之后想到的insert方法,是错的。因为current为null的时候,用newNode替代current,但是此时的current已经是null,和原来的节点不存在子节点的关系。

public void insert(int key){
        Node newNode = new Node(key);
        if (root == null){
            root = newNode;
            return;
        }
        Node current = root;
        while (true){
            if (key < current.key){
                current = current.left;
                if (current == null){
                    current = newNode;
                    return;
                }
            } else {
                current = current.right;
                if (current == null){
                    current = newNode;
                    return;
                }
            }
        }
    }
需要新建立一个节点(parent代替),然后用parent.left指向新插入的节点,将整个tree连接起来。
    public void insert(int key){
        Node newNode = new Node(key);
        if (root == null){
            root = newNode;
            return;
        }
        Node current = root;
        Node parent = null;
        while (true){
            parent = current;
            if (key < current.key){
                current = current.left;
                if (current == null){
                    parent.left = newNode;
                    return;
                }
            } else {
                current = current.right;
                if (current == null){
                    parent.right = newNode;
                    return;
                }
            }
        }
    }


find() 函数,如果未找到值,则返回-1。返回类型其实也可以改成boolean。

    //Return -1 if not found
    public int find(int key){
        if (root == null) return -1;
        Node current = root;
        while (true){
            if (key < current.key){
                current = current.left;
            } else if (key > current.key){
                current = current.right;
            } else {
                return current.key;
            }
        }
    }

remove()方法是BST的难点,要分类讨论。

    1. 要删除的node(current)没有child. 此时只要将该node的parent子节点设置为null。加入了boolean类型变量isLeftChild要判断要删除的node是left child or right child, if it is a left child, then set parent.left = null; otherwise set parent.right = null;

    2. 要删除的node(current)只有left child或right child. 比如只有left child时,还是要用到isLeftChild变量,当current是左节点时,set parent.left = current.left.  current是右节点时, set parent.right = current.left.

    3. 要删除的node(current)既有left child 也有right child. 以right child 为新的root,寻找最小值min作为代替current的replacement(代码中getReplacement函数),找到replacement之后记得要将被取出的replacement下的节点与replacementParent连接起来。同样需要用到isleftchild变量。

    public boolean remove(int key){
        Node current = root;
        Node parent = null;
        boolean isLeftChild = true;
        while (current.key != key){
            parent = current;
            if (key < current.key){
                current = current.left;
                isLeftChild = true;
            } else if (key > current.key){
                current = current.right;
                isLeftChild = false;
            } else {
                return false;
            }
        }
        //The node to be removed has no child
        if (current.left == null && current.right == null){
            if (current == root){
                root = null;
            }
            if (isLeftChild){
                parent.left = null;
            } else {
                parent.right = null;
            }
        }
        //The node to de removed has left child
        else if (current.left != null && current.right ==null){
            if (current == root){
                root = root.left;
            } else if (isLeftChild){
                parent.left = current.left;
            } else {
                parent.right = current.left;
            }
        }

        else if (current.left == null && current.right != null){
            if (current == root){
                root = root.right;
            } else if (isLeftChild){
                parent.left = current.right;
            } else {
                parent.right = current.right;
            }
        }

        else {
            Node replacement = getReplacement(current);
            if (current == root){
                root = replacement;
            } else if (isLeftChild){
                parent.left = replacement;
            } else {
                parent.right = replacement;
            }
            replacement.left = current.left;
        }
        return true;
    }

    public Node getReplacement(Node removeNode){
        Node replacement = null;
        Node replacementParent = null;
        Node current = removeNode.right;
        while(current != null){
            replacementParent = replacement;
            replacement = current;
            current = current.left;
        }
        if (replacement != removeNode.right){
            replacementParent.left = replacement.right;
            replacement.right = removeNode.right;
        }
        return replacement;
    }

猜你喜欢

转载自blog.csdn.net/everest115/article/details/79587501