开发者

why this program has seg fault?

开发者 https://www.devze.com 2023-03-27 12:12 出处:网络
I am a C++ newbie, not quite understand the destruction workflow of this program, so I write destructor for both classes. But got error...Do I bother defining the destructor of Node?

I am a C++ newbie, not quite understand the destruction workflow of this program, so I write destructor for both classes. But got error... Do I bother defining the destructor of Node?

#include<iostream>
using namespace std;

// in this case, the BST doesn't have duplicates
class Node
{
public:
    Node* parent;
    Node* left;
    Node* right;
    Node() : key(-1), parent(NULL), left(NULL), right(NULL) {}
    virtual ~Node() {cout << "destructor of Node" << endl; delete parent; delete left; delete right;}
    void setKey(int k)
    {
        key = k;
    }
    int getKey() {return key;}
private:
    int key;
};


class BST
{
public:
    Node* root;
    BST() {root = NULL;}
    virtual ~BST() {freeNode(root);}
    void addNode(int key)
{
    if (!root)
    {
        root = new Node();
        root->setKey(key);
    }
    else 
        addNode(key, root);
}
Node* findNode(int key)
{
    Node* p = root;
    while (p)
    {
        if (p->getKey() == key)
            return p;
        else if (p->getKey()<=key)
        {
            p = p->right;
        }
        else
            p = p->left;
    }
    return p;
}
void walk(Node* node)
{
    if (node)
    {
        walk(node->left);
        cout << node->getKey() << " " << flush;
        walk(node->right);
    }
}
void deleteNode(int key)
{
    Node* p = findNode(key);
    if (p)
    {
        //case 1: p has no children
        if (!p->right && !p->left)
            p->parent->right == p ? p->parent->right = NULL : p->parent->left = NULL;
        //case 2: p has one child
        else if (!p->left && p->right)
        {
            p->parent->right = p->right;
            freeNode(p);
        }
        else if (!p->right && p->left)
        {
            p->parent->left = p->left;
            freeNode(p);
        }
        //case 3: p has two children
        else
        {
            Node *suc = successor(key);
            exchange(suc,p);
            deleteNode(suc->getKey());
        }

    }
}
Node* min(Node* node)
{
    //empty tree
    if (!node)
        return NULL;
    else if (!node->left)
        return node;
    else
        return min(node->left);
}
Node* max(Node* node)
{
    //empty tree
    if(!node)
        return NULL;
    else if (!node->right)
        return node;
    else 
        return max(node->right);
}
Node* successor(int key)
{
    Node *temp = NULL;
    Node *p = findNode(key);
    //case 1: has a right child
    if (p->right)
        return min(p->right);
    //case 2: does not have a right child
    else
    {
        temp = p->parent;
        while(temp->left != p)
        {
            p = temp;
            temp = temp->parent;
        }
        return temp;
    }
}

Node* predecessor(int key)
{
    Node *temp = NULL;
    Node *p = findNode(key);
    //case1: has a left child
    if (p->left)
        return max(p->left);
    //case2: does not have a left child
    else
    {
        temp = p->parent;
        while(temp->right != p)
        {
            p = temp;
            temp = temp->parent;
        }
        return temp;
    }
}

private:
void addNode(int key, Node* node)
{
    if (node->getKey() <= key)
    {
        if (node->right)
            addNode(key, node->right);
        else
        {
            Node* leaf = new Node();
            leaf->setKey(key);
            leaf->parent = node;
            node->right = leaf;
        }
    }
    else
    {
        if (node->left)
            addNode(key, node->left);
        else
        {
            Node* leaf = new Node();
            leaf->setKey(key);
            leaf->parent = node;
            node->left = leaf;
        }
    }

}
void freeNode(Node* leaf)
{
    delete leaf;
}
void exchange(Node *a, Node *b)
{
    int temp = a->getKey();
    a->setKey(b->getKey());
    b->setKey(temp);
}
};

int main(int argc, char** args)
{
int *p = NULL;
dele开发者_StackOverflowte p;

BST tree;
tree.addNode(8);
tree.addNode(4);
tree.addNode(12);
tree.addNode(2);
tree.addNode(6);
tree.addNode(10);
tree.addNode(14);
tree.addNode(1);
tree.addNode(3);
tree.addNode(5);
tree.addNode(7);
tree.addNode(9);
tree.addNode(11);
tree.addNode(13);
tree.addNode(15);
tree.walk(tree.root);
return 0;
}


delete parent; delete left; delete right;

When you delete an object, its destructor is called. Here, both the left and the right node will delete the current one as they delete their parents. To fix this, simply remove parent deletion.

0

精彩评论

暂无评论...
验证码 换一张
取 消