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.
精彩评论