Splay旋转四步走
1、标记新根
root:=f[p].lch;
2、将新根的左/右节点接到旧根的右/左节点上
//====== 左旋 ====== f[p].rch:=f[root].lch; f[f[p].rch].fa:=p; //====== 右旋 ====== f[p].lch:=f[root].rch; f[f[p].lch].fa:=p;
3、改写新根与其父亲之间的关系
if p<>h then if f[f[p].fa].lch=p then f[f[p].fa].lch:=root else f[f[p].fa].rch:=root else h:=root; f[root].fa:=f[p].fa;
4、标记新根和旧根之间的关系
//====== 左旋 ====== f[root].lch:=p; f[p].fa:=root; //====== 右旋 ====== f[root].rch:=p; f[p].fa:=root;
用指针写时注意null的判断。如果需要更新信息(节点数)在最后要同步更新p和root。
附完整代码:
Procedure zig(P:longint); var root:longint; begin root:=f[p].rch; if p<>h then if f[f[p].fa].lch=p then f[f[p].fa].lch:=root else f[f[p].fa].rch:=root else h:=root; f[root].fa:=f[p].fa; f[p].rch:=f[root].lch; f[f[p].rch].fa:=p; f[root].lch:=p; f[p].fa:=root; pushup(p); pushup(root); end; Procedure zag(P:longint); var root:longint; begin root:=f[p].lch; if p<>h then if f[f[p].fa].lch=p then f[f[p].fa].lch:=root else f[f[p].fa].rch:=root else h:=root; f[root].fa:=f[p].fa; f[p].lch:=f[root].rch; f[f[p].lch].fa:=p; f[root].rch:=p; f[p].fa:=root; pushup(p); pushup(root); end;