为什么这个程序有段错误?

时间:2011-08-11 03:00:54

标签: c++ segmentation-fault

我是一个C ++新手,不太了解这个程序的破坏工作流程,所以我为这两个类编写了析构函数。但是得到了错误......我是否还在定义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;
delete 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;
}

1 个答案:

答案 0 :(得分:2)

delete parent; delete left; delete right;

删除对象时,会调用其析构函数。这里,左侧和右侧节点将删除当前节点,因为它们删除了父节点。要解决此问题,只需删除父删除。