我正在努力实现一个splay树。插入工作完美,但是当我尝试以Z字形或锯齿形方式展开插入的节点时,我总是会遇到分段错误。当要展开的节点没有祖父母时使用的左右旋转完美地工作。
这是右右Zig-Zig旋转的代码。如果我这样做,例如
insert("z", 1);
insert("j", 1);
insert("p", 1);
zigZigRotate(root.get_left().get_left());
我得到了j和p的无限循环。 insert的第一个参数是键,第二个是rank(用于顺序遍历)。
因此,在上一个示例中,在展开之前,树看起来像: ž Ĵ P
由于z插入位置1,然后j插入位置1,将z移动到位置2,等等。
这是我用于右右旋转的zig-zig代码。
if (n == n->get_parent()->get_left())
{
if (n->get_right() != nullptr)
{
n->get_right()->set_parent(n->get_parent());
}
if (n->get_parent()->get_right() != nullptr)
{
n->get_parent()->get_right()->set_parent(n->get_parent()>get_parent());
}
n->get_parent()->get_parent()->set_parent(n->get_parent());
n->get_parent()->set_parent(n);
n->get_parent()->get_parent()->set_left(n->get_parent()->get_right());
n->get_parent()->set_right(n->get_parent()->get_parent());
n->get_parent()->set_left(n->get_right());
n->set_right(n->get_parent());
n->set_parent(n->get_parent()->get_parent()->get_parent());
}
我已经跟踪了它,它似乎应该正确地旋转给我。没有无限循环应该发生的地方。但既然如此,我会假设j和p以某种他们不应该的方式连接在一起。例如j将p作为其左子,但由于某种原因,p将j作为其子项之一。
答案 0 :(得分:1)
看起来所有这些链接更改的操作顺序不正确,或者您需要在进行更改之前将其中一些链接存储在局部变量中。通过它在纸上工作。
n->get_parent()->set_parent(n);
行改变了n
的祖父母。在此之后,对n->get_parent()->get_parent()
的调用将返回n
。这可能会导致树中出现循环。
(我假设n->get_parent()>get_parent()
是一种类型,而->
意图而不是比较。)