我遇到二进制搜索树指针的问题,无法确定原因。我有一个功能,我在其中取两棵树并在预定位置交换树的两个子树。这是进行交换的代码。
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指针。
这里有两个问题:
首先,交换可以创建一个节点只有一个子节点的情况。我没有成功确定这是怎么回事。
第二,也许是相关的一点信息,一旦这个> lChild设置为tmp2-> lChild和this-> rChild = tmp2-> rChild,我已经插入了一个检查是否secondParentNode- > lChild或secondParentNode-> rChild为null。这会导致段错误至少有些一致。
克隆(深层复制)功能不起作用吗?如果是这样,为什么不呢?任何关于可能导致这些问题的想法都会受到赞赏。
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;
}
}
答案 0 :(得分:0)
如果rChild
或lChild
为nullptr
,则调用rChild->clone();
或lChild->clone()
会导致细分错误。
我们可以将函数重写为:
void opNode::clone(opNode* n)
{
if (n)
{
n->val = val;
n->operation = operation;
if (rChild)
{
if (n->rChild)
{
// release all right children.
}
n->rChild = new opNode;
clone(n->rChild);
}
if (lChild)
{
if (n->lChild)
{
// release all left children nodes.
}
n->lChild = new opNode;
clone(n->lChild);
}
}
}
交换代码可简化如下:
opNode* tmp = new opNode;
clone(tmp);
secondParentNode->clone(this);
tmp->clone(secondParentNode);