【发布时间】:2016-11-21 01:23:15
【问题描述】:
我对二叉搜索树指针有疑问,无法确定原因。我有一个函数,我取两棵树并在预定位置交换两棵树的子树。这是进行上述交换的代码。
opNode* tmp = new opNode();
opNode* tmp2 = new opNode();
tmp = this->clone();
tmp2 = secondParentNode->clone();
this->operation = tmp2->operation;
this->val = tmp2->val;
this->lChild = tmp2->lChild;
this->rChild = tmp2->rChild;
secondParentNode = tmp;
此时我已经确定了要交换的每个子树的位置。 "this" 指针代表第一个交换点,secondParentNode 是一个 opNode 指针,代表第二个。
这里有两个问题:
第一个是交换可以创建一个节点只有一个孩子的情况。我无法确定这是如何发生的。
第二,也许是相关的信息,一旦 this->lChild 设置为 tmp2->lChild 并且 this->rChild = tmp2->rChild,我插入了一个检查是否是 secondParentNode->lChild 或 secondParentNode -> rChild 为空。这至少会导致段错误。
克隆(深拷贝)功能不起作用吗?如果是这样,为什么不呢?对于可能导致这些问题的任何想法,我们将不胜感激。
opNode 是我的节点类:
struct opNode
{
string operation;
double val;
opNode* lChild;
opNode* rChild;
opNode* clone();
};
以及相关的克隆功能:
opNode* opNode::clone()
{
if(this != nullptr)
{
opNode* n = new opNode();
n->val = val;
n->operation = operation;
n->rChild = rChild->clone();
n->lChild = lChild->clone();
return n;
}
return nullptr;
}
编辑* 根据要求,交换功能。 randPoint1 和 randPoint2 由 uniform distribution 确定:
uniform_int_distribution<int> dist(0, mate[k].root->count(0) - 1);
其中 mate[k] 是根树指针,count 定义为:
int opNode::count(int c)
{
if(this != nullptr)
{
c++;
if(lChild != nullptr)
c += lChild->count(0);
if(rChild != nullptr)
c += rChild->count(0);
return c;
}
return 0;
}
兑换功能:
void opNode::recombination(opNode*& secondParentNode, int& randPoint1, int& randPoint2, bool& done)
{
if(done)
return;
if(secondParentNode != nullptr && !done)
{
if(randPoint2 > 0 && secondParentNode->lChild != nullptr)
{
randPoint2--;
recombination(secondParentNode->lChild, randPoint1, randPoint2, done);
}
if(randPoint2 > 0 && secondParentNode->rChild != nullptr)
{
randPoint2--;
recombination(secondParentNode->rChild, randPoint1, randPoint2, done);
}
}
if(this != nullptr && randPoint2 == 0 && !done)
{
if(randPoint1 > 0 && lChild != nullptr)
{
randPoint1--;
lChild->recombination(secondParentNode, randPoint1, randPoint2, done);
}
if(randPoint1 > 0 && rChild != nullptr)
{
randPoint1--;
rChild->recombination(secondParentNode, randPoint1, randPoint2, done);
}
}
if(this != nullptr && secondParentNode != nullptr && randPoint1 == 0 && randPoint2 == 0 && !done)
{
opNode* tmp = new opNode();
opNode* tmp2 = new opNode();
tmp = this->clone();
tmp2 = secondParentNode->clone();
this->operation = tmp2->operation;
this->val = tmp2->val;
this->lChild = tmp2->lChild;
this->rChild = tmp2->rChild;
secondParentNode = tmp;
}
}
【问题讨论】:
-
顺便说一句(我投票关闭,因为您没有提供有用的示例),但是您的第一个代码 sn-p 出于某种原因泄漏了两个节点。此外,“无法阅读的文字墙”也不适合提问。
-
在这种情况下,你认为什么是有用的例子?
-
虽然二叉树并不是最复杂的数据结构,但从
tmp=new OpNode();... tmp =this-_clone()或this != nullptr可以明显看出您仍然是初学者。即使我是你的同事,我也不会开始调试这个。问题是你写了太多没有测试的代码。 -
我已经迫不及待地想进入下一个级别,我会说 tmp = clone() 或 if(this)。非常规是否等同于缺乏知识?它略显冗长。我对我自己构建的这种数据结构的工作不多,所以在这方面你是正确的。我还测试了我需要单独编写的每个函数,并观察到了积极的结果。在这种情况下,我想它会显示一个彻底的驱动程序功能的价值。虽然,在这种情况下,我缺乏解决这种极端情况的知识,所以我不会写任何驱动程序来帮助。因此问题。
-
This 是一个有用的例子的定义。讽刺也不好看。当 MSalters 指出
if(this != nullptr)风格不佳时,这并不是因为您可以改用if(this),而是因为在 null 对象上调用方法是无效的,因此您在到达之前已经调用了未定义的行为查看。如果它可能是真的,那么您的代码已经是静态错误的。如果不能,则说明您编写了额外的逻辑,表明您不了解自己的代码的行为方式。
标签: c++ pointers binary-tree deep-copy