簡體   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