удалить узел в BBST

0

Удаление узла (значение 8 или 2) не работает. Остальная часть кода работает нормально. Даже удаление узла 4 работает. Я не могу понять проблему.

Код: В функции main() я создал сбалансированное двоичное дерево поиска из 1D-вектора.

#include <iostream>
#include <vector>


using namespace std;

class TNode
{
public:
    TNode(){}
    ~TNode(){ std::cout <<"TNode destroyed" << endl; }
    TNode *left;
    TNode *right;
    int data;
};

////////////////////////////////////////////////////////////////////
//////////////////////////   TREE   ////////////////////////////////
////////////////////////////////////////////////////////////////////
class TREE
{
public:
    TREE(){}
    ~TREE(){}
    TNode* createBBST(std::vector<int>& arr, int startIdx, int endIdx);
    void preOrderTraverseBT(TNode *node);
    void inOrderTraverseBT(TNode *node);
    void postOrderTraverseBT(TNode *node);
    TNode* searchBBST(TNode *rootnode, int data);
    TNode* insertBBST(TNode *rootnode, int data);
    void deleteBBST(TNode *rootnode, int data);
    TNode* findPred(TNode *rootnode);
};

TNode* TREE::createBBST(std::vector<int>& arr, int startIdx, int endIdx)
{
    //base-case
    if(startIdx>endIdx)
        return NULL;

    /* Get the middle element and make it root */
    TNode *root = new TNode;
    int mid = (startIdx+endIdx)/2;
    root->data = arr[mid];

    /* Recursively construct the left subtree and make it left child of root */
    root->left = createBBST(arr, startIdx, mid-1);

    /* Recursively construct the right subtree and make it right child of root */
    root->right = createBBST(arr, mid+1, endIdx);

    return root;
}

void TREE::preOrderTraverseBT(TNode *node)
{

    if(node==NULL)
        return;
    cout << node->data << " ";
    preOrderTraverseBT(node->left);
    preOrderTraverseBT(node->right);

    return;
}

void TREE::inOrderTraverseBT(TNode *node)
{

    if(node==NULL)
        return;

    inOrderTraverseBT(node->left);
    cout << node->data << " ";
    inOrderTraverseBT(node->right);

    return;
}



TNode* TREE::searchBBST(TNode *rootnode, int data)
{
    if(rootnode==NULL)
        return NULL;    

    if(rootnode->data == data)
        return rootnode;
    else if(rootnode->data > data){
        return searchBBST(rootnode->left, data);
    }
    else //if(rootnode->data < data)
        return searchBBST(rootnode->right, data);   
}

TNode* TREE::insertBBST(TNode *rootnode, int data)
{   

    if(rootnode->data >= data)
    {
        if(rootnode->left==NULL)
        {
            rootnode->left = new TNode;
            rootnode->left->left=NULL; rootnode->left->right=NULL;
            rootnode->left->data = data;
            return rootnode->left;
        }
        else// if(rootnode->left!=NULL)
        {
            return insertBBST(rootnode->left, data);
        }       
    }
    else// if(rootnode->data < data)
    {
        if(rootnode->right==NULL)
        {
            rootnode->right = new TNode;
            rootnode->right->left=NULL; rootnode->right->right=NULL;
            rootnode->right->data = data;
            return rootnode->right;
        }
        else// if(rootnode->right!=NULL)
        {
            return insertBBST(rootnode->right, data);
        }   
    }

    //
}

TNode* TREE::findPred(TNode *rootnode)
{
    if(rootnode==NULL)
        return rootnode;

    return findPred(rootnode->right);
}

void TREE::deleteBBST(TNode *rootnode, int data)
{
    cout << "Delete node : " << data  << endl;

    TNode *deletenode = searchBBST(rootnode, data);

    TNode* temp = NULL;
    if(deletenode->left==NULL && deletenode->right==NULL) /* 0 Child */
    {
        cout << "0 child..." << endl;

        delete deletenode;
        deletenode = NULL;

        inOrderTraverseBT( rootnode );
        cout << "\ndeleted..."<<endl;
    }
    else if(deletenode->left!=NULL && deletenode->right==NULL) /* 1 Child */
    {
        cout << "1 child..." << endl;
        //copy left child to its parent
        temp = deletenode->left;
        deletenode->data = temp->data;
        deletenode->left = temp->left;
        deletenode->right = temp->right;

    }
    else if(deletenode->left==NULL && deletenode->right!=NULL) /* 1 Child */
    {
        cout << "1 child..." << endl;
        temp = deletenode->right;
        deletenode->data = temp->data;
        deletenode->right = temp->right;    
        deletenode->left = temp->left;          
    }
    else /* 2 Children */
    {
        cout << "2 child..." << endl;
        //find predecessor
        TNode* pred = findPred(deletenode->left);

        //if pred has no child
        if(pred->left == NULL)
        {
            deletenode->data = pred->data;
        }
        else
        {
            //if pred has a left child
            deletenode->data = pred->data;
            pred->data = pred->left->data;
            pred->left = pred->left->left;
        }

        delete pred;
        pred = NULL;
    }

    //delete the old left child
    delete temp;
    temp = NULL;
}

////////////////////////////////////////////////////////////////////
//////////////////////////   main   ////////////////////////////////
////////////////////////////////////////////////////////////////////
int main(int argc, char const *argv[])
{

    std::vector<int> vec(5);
    for (int i = 0; i < vec.size(); ++i)
        vec[i] = i;

    TREE aTree;
    TNode* root =  aTree.createBBST(vec, 0, vec.size()-1);

    //print the resulted BBST
    aTree.inOrderTraverseBT( root );

    //search a key
    TNode* node = aTree.searchBBST(root, 3);
    if(node != NULL)
        cout << "node->data = " << node->data << endl;
    else
        cout << "Key not found..." << endl;

    //insert
    cout << "Insert node : 3" << endl;
    aTree.insertBBST(root, 3);
    aTree.inOrderTraverseBT( root );


    cout << "Insert node : 8"  << endl;
    aTree.insertBBST(root, 8);
    aTree.inOrderTraverseBT( root );
    aTree.deleteBBST(root, 8);
    // aTree.inOrderTraverseBT( root );

    return 0;
}
Теги:
pointers
binary-search-tree

1 ответ

0

В TREE::deleteBBST в случае "0-й ребенок" (который имеет 8-й узел):

delete deletenode;
deletenode = NULL;

Но deletenode - это локальный указатель, который указывает на узел в дереве. Таким образом, вы удаляете узел, но дерево все еще содержит указатель на него. Более поздние операции разыгрывают этот указатель, что приводит к неопределенному поведению.

Я предлагаю вам изменить дерево, чтобы полностью удалить узел и обновить узлы, указывающие на него, прежде чем вы удалите его.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню