我在使用C ++对数据结构进行排序时,我正在编写一堆函数来创建二进制搜索树类。在尝试创建复制构造函数/函数来复制树时,我有点迷失。
void BST<T>::copyBST(Node* treeOriginal, Node* treeNew){
if (treeOriginal == NULL) //base case to end recursion when at tree end
treeNew == NULL;
else{
Node* treeNew = new Node; //create the node and set the new key to original
treeNew->key = treeOriginal->key;
Node* leftChild = new Node; //create a left node to be child of new node
treeNew->left = leftChild;
leftChild->parent = treeNew;
Node* rightChild = new Node; //create a right node
treeNew->right = rightChild;
rightChild->parent = treeNew;
copyBST(treeOriginal->left, leftChild); //call copy function on subtree of left child
copyBST(treeOriginal->right, rightChild); //call copy function on subtree of right child
}
}
现在尝试运行时会发生一些事情。首先,它不会复制所有节点,每次都会复制不同的数量。这对我来说很奇怪,因为我在每个节点上调用一个递归,因为我从根开始然后在左边和右边调用它。我尝试在纸上写出这个过程,直观地规划它如何复制原始树,但对我而言,它似乎是一个逻辑过程,无法找到丢失的地方。
我还在函数中添加了cout语句,以打印出原始节点的密钥,地址,父级和子级,以及复制节点的密钥,地址,父级和子级。我在此测试中发现的唯一问题是复制节点的父地址始终为00000000或NULL。显然是一段代码
leftChild->parent = treeNew; and rightChild->parent = treeNew;
实际上并没有将节点的父指针设置为父节点。
这是我在尝试解决此问题时可以找到的唯一明确问题。我不确定如何寻找问题。如果您无法在代码逻辑中看到任何问题,那么有没有人对如何找到问题所在的任何其他想法?
谢谢!
答案 0 :(得分:3)
您对treeNew
的声明会创建一个按值调用的参数。这意味着调用者永远不会看到对此变量的更改。您必须将此参数设置为参数,以便可以修改调用者的指针。然后递归复制子树非常简单:
void BST<T>::copyBST(Node* treeOriginal, Node *parent, Node*& treeNew){
if (treeOriginal == NULL) //base case to end recursion when at tree end
treeNew == NULL;
else{
Node* treeNew = new Node; //create the node and set the new key to original
treeNew->key = treeOriginal->key;
treeNew->parent = parent;
// Just call recursively to copy the subtrees:
copyBST(treeOriginal->left, treeNew, treeNew->left);
copyBST(treeOriginal->right, treeNew, treeNew->right);
}
}
注意&
添加到第二个参数类型。更常见的习惯用法是使用函数返回值:
Node* BST<T>::copyOf(Node* treeOriginal, Node *parent){
if (treeOriginal == NULL) //base case to end recursion when at tree end
return NULL;
//create the node and set the new key to original
Node* treeNew = new Node;
treeNew->key = treeOriginal->key;
treeNew->parent = parent;
// Just call recursively to copy the subtrees:
treeNew->left = copyOf(treeOriginal->left, treeNew);
treeNew->right = copyOf(treeOriginal->right, treeNew);
return treeNew;
}