【问题标题】:Delete a node from a binary search tree从二叉搜索树中删除一个节点
【发布时间】:2015-04-25 23:36:24
【问题描述】:

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

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

  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;
     }
}

【问题讨论】:

  • 这个问题中[node.js]是如何使用的?
  • 假设是我的错误的节点。你能帮忙吗?

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


【解决方案1】:

这里是所有可能情况的完整二叉树删除实现:

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;
}

【讨论】:

  • 第三种情况是什么?
【解决方案2】:

删除具有leftright 子节点的节点时,您必须遵循delete by merging 方法

您的 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;
}

【讨论】:

    猜你喜欢
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多