我的代码是
private Node rotateLeftChild(Node n)
{
Node o = n.left;
n.left = o.right;
o.right = n;
return o;
}
当我打电话给它时,在根处旋转这样的树:
7
/ \
4 8
/ \
1 5
它删除了4和1,并将5作为7的左根。我尝试将该方法设为无效方法,但这似乎也不起作用。我是以完全错误的方式去做的吗?
答案 0 :(得分:2)
首先,抱歉我的英语。
回答问题 - 为什么节点4消失很简单。 7有父节点(或7是root)。当你调用rotateLeftChild时,7的父母仍在“思考”他的孩子是7岁,而不是4岁:
所以,有树解决方案:
建立父节点的链接并进行更新。在leftRotation的末尾,分别进行赋值,n.Parent.Left = o或n.Parent.Right = o(if(n.Parent.Left == n)或(n.Parent.Right == n))。当然,当您旋转root的子级时,必须更新树根的链接。
当您添加|时插入|查找节点,保存堆栈中的所有先前(父)节点,然后在轮换后,您必须更新其子节点的链接。或者像这样使用递归:
private Splay(Node parent, Node cur, Node n, bool canMoveUpTwice = false) {
if (cur.Value > n.Value)
Splay(cur, cur.Left, n, !canMoveUpTwice);
else
Splay(cur, cur.Right, n, !canMoveUpTwice);
if (canMoveUpTwice)
MoveUpTwice();
else
MoveUpOnce();
if (parent.Left == cur)
parent.Left = n;
else
parent.Right = n;
if (Parent == null)
tree.Root = n;
}
如何使用。添加节点后,必须运行Splay(root,newNode)。确定,你会发现堆栈溢出。
您必须交换节点的值,然后才能认为节点已被交换。在标准的旋转实现中我们有这样的图片: 在使用交换轮换时,我们得到这个(= x表示“节点具有值X”): 所以,我们有这个代码
private rotateLeftChild(Node q) {
Node p = q.Left;
Swap(q.Value, p.Value);
A = p.Left;
B = p.Right;
C = q.Right;
q.Left = A;
q.Right = p;
p.Left = B;
p.Right = C;
}
小心:代码尚未经过测试。