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;
原文地址:https://www.cnblogs.com/htfy/p/2983425.html