繁体   English   中英

不递归地从二叉搜索树中删除一个节点

[英]Deleting a node from a binary search tree without recursion

我有一个二叉搜索树。 我想从中删除一个节点:

void deleteANode(struct node *head, int value) {
    //let us find the node
    struct node *temp = head;
    struct node *parent = NULL;

    //let us find the node
    while (temp != NULL) {
        if (value > temp->data) {
            parent = temp;
            temp = temp->right;
        } else
        if (value < temp->data) {
            parent = temp;
            temp = temp->left;
        } else {
            //let us check for child nodes
            //
            if (temp->left == NULL && temp->right == NULL) {
                printf("Deleting a leaf.\n");

                temp = NULL;
                printf("Set temp null.\n");
                free(temp);
                break;
            } else
            if (temp->left == NULL || temp->right == NULL) {
                printf("Deleting a one child.\n");
                //one of the child is null
                if (temp->left != NULL) {
                    parent->left = temp->left;
                } else {
                    parent->right = temp->right;
                }
                free(temp);
            } else {
                printf("Deleting two child parent.\n");
                //both of them are not NULL
                //need to find the pre-order successor
                struct node *temp2 = temp->right;

                while (temp2->left != NULL) {
                    temp2 = temp2->left;
                }
                //found the successor.
                temp->data = temp2->data;
                free(temp);
            }
            break;
        }
    }
}

我正在尝试删除此块中的叶节点:

if (temp->left == NULL && temp->right == NULL) {
    printf("Deleting a leaf.\n");

    temp->data = NULL;
    printf("Set temp null.\n");
    free(temp);
    break;
}

但是上面的代码不起作用。

我正在调用上面的方法:

deleteANode(head, 3);

前序遍历前后保持不变:

5 4 3 10 7 20 删除一片叶子。 设置临时零。 =============== 5 4 3 10 7 20

我究竟做错了什么。

根据@pstrjds 评论更新:

if (temp->left == NULL && temp->right == NULL ) {
    printf("Deleting a leaf.\n");
    parent->left = NULL;
    parent->right = NULL;
    free(temp);
    temp = NULL;
    printf("Set temp null.\n");
    break;
}

它对叶节点工作正常。 需要为有两个孩子的节点工作。

在删除叶子的代码块中,您实际上并没有释放节点,也没有更新父节点以不再指向它。

if ( temp -> left == NULL && temp -> right == NULL )
{
    printf("Deleting a leaf.\n");
    if (parent->left == temp)
    {
        parent->left = NULL;
    }
    else
    {
        parent->right = NULL;
    }

    free(temp);
    temp = NULL;
    printf("Set temp null.\n");
    break;
 }

您实际上可以删除行temp = NULL并更改break; 返回声明。

你的代码真的有效吗? 它应该是这样的:

printf("Deleting two child parent.\n");
Node* temp2 = temp->right;
while(temp2->left != NULL)
{
    parent = temp2;
    temp2 = temp2->left;
}

temp->data = temp2->data;
parent->left = NULL;
delete temp2;

return;

Java解决方案

// Java program to demonstrate delete operation in binary search tree 
class BinarySearchTree 
{ 
  /* Class containing left and right child of current node and key value*/
  class Node 
  { 
    int key; 
    Node left, right; 

    public Node(int item) 
    { 
        key = item; 
        left = right = null; 
    } 
} 

// Root of BST 
Node root; 

// Constructor 
BinarySearchTree() 
{ 
    root = null; 
} 

// This method mainly calls deleteRec() 
void deleteKey(int key) 
{ 
    root = deleteRec(root, key); 
} 

/* A recursive function to insert a new key in BST */
Node deleteRec(Node root, int key) 
{  Node x=root;
 Node parent =null;
    /* Base Case: If the tree is empty */
    while(x!=null)
    {
      if(x.key>key)
      { parent=x;
        x=x.left;
      }
      else if(x.key<key)
      {parent=x;
        x=x.right;
      }
      else
      {
        if(x.left==null&&x.right==null)
        {
         System.out.println(x.key+"y1");
          if(parent.left==x)
          parent.left=null;
          else if(parent.right==x)
          parent.right=null;

          x=null;

          break;
        }
        else
        {
          System.out.println(x.key+"y2");
          if(x.left==null)
          { 
            if(parent.right==x)
            parent.right=x.right;
            else if(parent.left==x)
             parent.left=x.right;
            System.out.println(x.key+"yes");
            x=null;
            break;
          }
          else if(x.right==null)
          {
            if(parent.left==x)
            parent.left=x.left;
            else if(parent.right==x)
            parent.right=x.left;
            x=null;
            break;
          }
          else
          {
            Node temp=x;
            Node px=null;
            temp=temp.right;
            while(temp.left!=null)
            { px=temp;
              temp=temp.left;
            }
            x.key=temp.key;
            if(px.left==temp)
            px.left=null;
            else if(px.left==temp)
            px.right=null;
            temp=null;
            break;
          }
        }
      }
    }
  return root;
} 

int minValue(Node root) 
{ 
    int minv = root.key; 
    while (root.left != null) 
    { 
        minv = root.left.key; 
        root = root.left; 
    } 
    return minv; 
} 

// This method mainly calls insertRec() 
void insert(int key) 
{ 
    root = insertRec(root, key); 
} 

/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) 
{ 

    /* If the tree is empty, return a new node */
    if (root == null) 
    { 
        root = new Node(key); 
        return root; 
    } 

    /* Otherwise, recur down the tree */
    if (key < root.key) 
        root.left = insertRec(root.left, key); 
    else if (key > root.key) 
        root.right = insertRec(root.right, key); 

    /* return the (unchanged) node pointer */
    return root; 
} 

// This method mainly calls InorderRec() 
void inorder() 
{ 
    inorderRec(root); 
} 

// A utility function to do inorder traversal of BST 
void inorderRec(Node root) 
{ 
    if (root != null) 
    { 
        inorderRec(root.left); 
        System.out.print(root.key + " "); 
        inorderRec(root.right); 
    } 
} 

// Driver Program to test above functions 
public static void main(String[] args) 
{ 
    BinarySearchTree tree = new BinarySearchTree(); 

    /* Let us create following BST 
        50 
    /    \ 
    30   70 
    / \ / \ 
    20 40 60 80 */
    tree.insert(50); 
    tree.insert(30); 
    tree.insert(20); 
    tree.insert(40); 
    tree.insert(70); 
    tree.insert(60); 
    tree.insert(80); 

    System.out.println("Inorder traversal of the given tree"); 
    tree.inorder(); 

    System.out.println("\nDelete 20"); 
    tree.deleteKey(20); 
    System.out.println("Inorder traversal of the modified tree"); 
    tree.inorder(); 

    System.out.println("\nDelete 30"); 
    tree.deleteKey(30); 
    System.out.println("Inorder traversal of the modified tree"); 
    tree.inorder(); 

    System.out.println("\nDelete 50"); 
    tree.deleteKey(50); 
    System.out.println("Inorder traversal of the modified tree"); 
    tree.inorder(); 
  } 
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM