从二叉搜索树中删除节点

时间:2015-04-25 23:36:24

标签: java binary-tree binary-search-tree nodes

我是二元搜索树的新手,删除一个节点给我带来了麻烦。我试图找出问题,看看我做错了什么,似乎仍然无法看到问题,我不想从其他网站复制代码。

我理解如何删除一个孩子或没有孩子的节点,我认为我的代码对于这些方法是正确的。我的问题是删除一个有两个孩子的节点。我不能让它正常工作。任何帮助或建议表示赞赏。

  public void DeleteNode(int number) {
         if (Root == null) 
         {
            JOptionPane.showMessageDialog(null," Tree Empty, can not delete ", JOptionPane.WARNING_MESSAGE);
                return;
         }
         Node child = Root;
         Node parent = Root;

         while (number != child.data) {
            if (number < child.data) 
            {
                parent = child;
                child = child.left;
            }
            else if (number > child.data) 
            {
                parent = child;
                child = child.right;
            }
            if(child == null){
                JOptionPane.showMessageDialog(null," Number not found",JOptionPane.WARNING_MESSAGE);
                        return;
            }
         }

         if(child.right == null && child.left == null)
         {
            hasNoChildren(child, parent);
         }
        else if(child.left != null && child.right != null)
         {
            hasTwoChildren(child, parent);
         }
         else if (child.right != null && child.left == null)
         {
             hasRightChild(child, parent);
         }
         else if (child.left != null && child.right == null)
         {
            hasLeftChild(child, parent);
         }
}

这是我删除有两个孩子的节点的方法

public void hasTwoChildren(Node child, Node parent)
{
    Node temp = null;
     if(child.data < parent.data){
         Node childorg = child;
         temp = child;
         child = child.left;
         while(child.right != null){
             temp = child;
             child = child.right;
         }
         childorg.data = child.data;
         if (child.left != null && child.right == null)
         {
            hasLeftChild(child, temp);
         }else{
             temp.right = null;
         }
     }
     else 
     {
         Node childorg = child;
         temp = child;
         child = child.right;
         while(child.left != null){
             temp = child;
             child = child.left;
         }
         childorg.data = child.data;
         if (child.left != null && child.right == null)
         {
            hasRightChild(child, temp);
         }else{
             temp.left = null;
         }
     }
}

这些是我删除没有子女或一个孩子的节点的方法

public void hasNoChildren(Node child, Node parent)
{
    if(child.data == Root.data)
     {
         Root = null;
     }
     else if(child.data < parent.data){
         parent.left = null;
     }else{
         parent.right = null;
     }
}
public void hasLeftChild(Node child, Node parent){
    if(child.data < parent.data){
            parent.left = child.left;
     }else{
         parent.right = child.left;
     }
}

public void hasRightChild(Node child, Node parent){
    if(child.data < parent.data){
            parent.left = child.right;
     }else{
         parent.right = child.right;
     }
}

2 个答案:

答案 0 :(得分:2)

以下是针对所有可能情况的完整二叉树删除实现:

public boolean delete(Node nodeToDelete) {
    boolean succes = false;
    Node nodeToRemove = findTheNodeToDelete(nodeToDelete);
    if (nodeToRemove == null) {
        return succes;
    }
    // case1; If the node has no children
    if (nodeToRemove.left == null && nodeToRemove.right == null) {
        if (nodeToRemove.parent.left.data == nodeToDelete.data) {
            nodeToRemove.parent.left = null;
            nodeToRemove = null;
            succes = true;
            return succes;
        } else if (nodeToRemove.parent.right.data == nodeToDelete.data) {
            nodeToRemove.parent.right = null;
            nodeToRemove = null;
            succes = true;
            return succes;

        }
        // case 2: if it has only one children
    } else if ((nodeToRemove.left == null && nodeToRemove.right != null)
            || (nodeToRemove.right == null && nodeToRemove.left != null)) {
        if (nodeToRemove.left != null) {
            nodeToRemove.parent.left = nodeToDelete.left;
            nodeToDelete = null;
            succes = true;
            return succes;

        } else if (nodeToRemove.parent.right != null) {
            nodeToRemove.parent.right = null;
            nodeToRemove = null;
            succes = true;
            return succes;
        }
    }
    // case 3 :
    if (nodeToRemove.left != null && nodeToRemove.right != null) {

        Node minLeftNode = findTheLeftMostNodeFromtheRightSubTree(nodeToRemove.right);

        System.out.println("----" + minLeftNode.data);

        // Now if the parent of the node is not null that means it is the
        // root
        // assign the left mode min as root and say
        // min.right=notetoRemove.right;

        // derefrence the min node /remove from the tree
        minLeftNode.parent.left = null;
        minLeftNode.parent = null;
        Node parentofTheNodeToDelete = nodeToRemove.parent;

        minLeftNode.parent = parentofTheNodeToDelete;
        Node rightOfNodeToDelete = nodeToRemove.right;
        Node leftofNodeToDelete = nodeToRemove.left;

        if (parentofTheNodeToDelete == null) {
            root = minLeftNode;
        } else {
            if (parentofTheNodeToDelete.right.data == nodeToDelete.data) {
                parentofTheNodeToDelete.right = minLeftNode;

            } else if (parentofTheNodeToDelete.left.data == nodeToDelete.data) {
                parentofTheNodeToDelete.left = minLeftNode;

            }

        }
        minLeftNode.right = rightOfNodeToDelete;
        minLeftNode.left = leftofNodeToDelete;
        nodeToRemove = null;
    }

    return succes;
}

答案 1 :(得分:1)

删除同时包含delete by mergingleft个孩子的节点时,您必须遵循right方法 enter image description here

hasTwoChildren()具有delete by merging逻辑的public void hasTwoChildren(Node child, Node parent) { Node rightNode = child.right; Node leftNode = child.left; // Delete child if (child.val < parent.val) parent.left = leftNode; else parent.right = leftNode; // Travel to the right most node of the leftNode Node tmp = leftNode; while (tmp.right != null) tmp = tmp.right; // set the rightNode tmp.right = rightNode; } 方法

$scope