我正在尝试用C ++创建二叉树数据结构的深层副本。问题是我使用的代码似乎只给我一个浅拷贝(这似乎导致我的解构函数出现问题)。
下面的代码是我的二叉树复制构造函数:
BinaryTreeStorage::BinaryTreeStorage(const BinaryTreeStorage ©tree):root(NULL)
{
root = copytree.root;
copyTree(root);
}
BinaryTreeStorage::node* BinaryTreeStorage::copyTree(node* other)
{
//if node is empty (at bottom of binary tree)
/*
This creates a shallow copy which in turn causes a problem
with the deconstructor, could not work out how to create a
deep copy.
*/
if (other == NULL)
{
return NULL;
}
node* newNode = new node;
if (other ->nodeValue == "")
{
newNode ->nodeValue = "";
}
newNode->left = copyTree(other->left);
newNode->right = copyTree(other->right);
return newNode;
}
任何帮助将不胜感激。 感谢
这是抛出内存异常的解构函数(我相信是因为我上面的浅拷贝)
BinaryTreeStorage::~BinaryTreeStorage(void)
{
try
{
destroy_tree();//Call the destroy tree method
delete root;//delete final node
}
catch(int &error)
{
cout << "Error Message : " << error << endl;
}
}
void BinaryTreeStorage::destroy_tree()
{
destroy_tree(root);
}
void BinaryTreeStorage::destroy_tree(node *leaf)
{
if(leaf!=NULL)
{
//Recursively work way to bottom node
destroy_tree(leaf->left);
destroy_tree(leaf->right);
//delete node
delete leaf;
}
}
答案 0 :(得分:4)
您没有执行根节点的深层副本,只执行其子节点。
不应该是:
root = copyTree(copytree.root);
编辑:此外,您两次销毁root
:
destroy_tree();//Call the destroy tree method
//once here
//remove this line
delete root;//delete final node
和
if(leaf!=NULL)
{
//Recursively work way to bottom node
destroy_tree(leaf->left);
destroy_tree(leaf->right);
//one more time here
delete leaf;
}
如果您只执行其中一项修复,问题将无法解决。
答案 1 :(得分:1)
实际上,我认为我们可以直接使用复制构造函数来递归深度复制树。假设该类定义如下:
class TreeNode {
public:
TreeNode() : value(), count(0), left(nullptr), right(nullptr) {}
TreeNode(const TreeNode &);
~TreeNode();
TreeNode &operator=(const TreeNode &);
// Other members...
private:
std::string value;
int count;
TreeNode *left;
TreeNode *right;
// Note that the valid state for the `left` and `right` pointer is either
// `nullptr` or a subtree node. So that we must check these pointers every
// time before dereferencing them.
};
然后复制构造函数是
TreeNode::TreeNode(const TreeNode &n)
: value(n.value), count(n.count), left(nullptr), right(nullptr) {
if (n.left)
left = new TreeNode(*n.left); // recursively call copy constructor
if (n.right)
right = new TreeNode(*n.right); // recursively call copy constructor
}
递归将在叶节点处停止,因为它的两个子节点都是nullptr
。
析构函数也是如此。
TreeNode::~TreeNode() {
delete left; // recursively call destructor on left subtree node
delete right; // recursively call destructor on right subtree node
}
当left
或right
为nullptr
时,delete
将不执行任何操作,以便停止递归。
您可以看到here的完整代码。