C ++从二叉搜索树中删除节点

时间:2016-10-26 12:51:07

标签: c++ binary-search-tree

我已经构建了一个二叉搜索树,并插入了一些随机值节点。我试图实现一个删除节点的功能,但由于某种原因它不起作用。尝试删除给定节点时,似乎已删除节点的父节点和已删除节点的子节点不会“连接”。

谁能看到我做错了什么?我已经多次尝试调试程序,看看我的错误在哪里,但我不明白如何将父母和孩子联系在一起。

这是我的计划:

#include <iostream>
using namespace std;

struct Node
{
    int data;   
    Node* left; 
    Node* right;
};

Node* insertNode(Node* root, int n);
Node* newNode(int d);
Node* deleteNode(Node* root, int d);
Node* findMin(Node* root);

int main()
{
    int num;
    Node* rootPtr = NULL;
    Node* min;

    rootPtr = insertNode(rootPtr, 15);
    rootPtr = insertNode(rootPtr, 10);
    rootPtr = insertNode(rootPtr, 20);
    rootPtr = insertNode(rootPtr, 24);
    rootPtr = insertNode(rootPtr, 7);
    rootPtr = insertNode(rootPtr, 25);
    rootPtr = insertNode(rootPtr, 5);

    rootPtr = deleteNode(rootPtr, 7);

    cout << "\nEnter a number to search for: ";
    cin >> num;
    if(search(rootPtr, num))
        cout << "\nFound.";
    else
        cout << "\nNot found.";

    cout << endl;
    return 0;
}

Node* insertNode(Node* root, int n)
{
    if(root == NULL)                                
        root = newNode(n);                          
    else if(n <= root->data)                        
        root->left = insertNode(root->left, n);     
    else if(n > root->data)                         
        root->right = insertNode(root->right, n);
    return root;                                    
}

Node* newNode(int d)
{
    Node* newNode = new Node();             
    newNode->data = d;                      
    newNode->left = newNode->right = NULL;
    return newNode;                         
}

bool search(Node* root, int d)
{
    if(root == NULL)                    
        return false;
    else if(root->data == d)            
        return true;
    else if(d < root->data)             
        return search(root->left, d);   
    else if(d > root->data)             
        return search(root->right, d);  
}

Node* deleteNode(Node* root, int d)
{
    if(root == NULL)
        return root;
    else if(d < root->data)
        deleteNode(root->left, d);
    else if(d > root->data) 
        deleteNode(root->right, d);
    else
    {
        if(root->left == NULL && root->right == NULL)
        {
            delete root;
            root = NULL;
        }
        else if(root->left == NULL)     
        {
            Node* temp = root;      
            root = root->right;         
            delete temp;                
        }
        else if(root->right == NULL)    
        {
            Node* temp = root;          
            root = root->left;          
            delete temp;                
        }
        else
        {
            Node* temp = findMin(root->right);
            root->data = temp->data;            
            root->right = deleteNode(root->right, temp->data);
        }
    }
    return root;
}

Node* findMin(Node* root)
{
    if(root == NULL)
        cout << "\nThe tree is empty.";
    else
    {
        Node* temp = root;          
        while(temp->left != NULL)   
            temp = temp->left;      
        return temp;                
    }
}

2 个答案:

答案 0 :(得分:1)

deleteNode()函数中,节点未在递归的返回路径中连接。您可能需要像使用insertNode()一样使用函数的返回值。例如,

else if(d < root->data)
    deleteNode(root->left, d);
else if(d > root->data) 
    deleteNode(root->right, d);

可能是(类似的)

else if(d < root->data)
    root->left = deleteNode(root->left, d);
else if(d > root->data) 
    root->right = deleteNode(root->right, d);

此外,findMin()的调用者可能需要min节点及其父节点。让它回归。在deleteNode()中,您可能需要将父项的子指针之一设置为NULL。

答案 1 :(得分:0)

删除节点时,还需要将存储在父节点中的指针设置为NULL。

假设您有节点P和C,其中P.left = C,C是叶节点。您的代码将为C释放内存,并将临时变量(在程序中称为root)设置为NULL。 (BTW使用nullptr而不是NULL。)但是如果你检查P的内容,它仍然引用了C的解除分配地址。