伸展树与半伸展树Java实现
伸展树与半伸展树属于自组织的数据结构,能按访问频率调整节点的位置
调整一般通过如下方式:
1)绕根的单旋转,跟AVL的单旋转类似
2)一字型旋转(ZigZig Rotation)
3)之字形旋转(ZigZag Rotation)
旋转操作较简单,有点点繁琐。
半伸展树不做完全的一字型旋转,它只让父节点绕祖父节点做单旋转。
不管怎样,每次访问(插入/查找 ,删除时展开被删除父节点)后把该节点调整到根节点的位置
伸展树代码:
调整一般通过如下方式:
1)绕根的单旋转,跟AVL的单旋转类似
2)一字型旋转(ZigZig Rotation)
3)之字形旋转(ZigZag Rotation)
旋转操作较简单,有点点繁琐。
半伸展树不做完全的一字型旋转,它只让父节点绕祖父节点做单旋转。
不管怎样,每次访问(插入/查找 ,删除时展开被删除父节点)后把该节点调整到根节点的位置
伸展树代码:
package
algorithms.tree;
/**
* @author yovn
*
*/
public class SplayTree < E extends Comparable < E >> extends DefaultBSTree < E > implements BSTree < E > {
static class SplayTreeNode < E extends Comparable < E >> extends BSTNode < E >
{
SplayTreeNode < E > parent;
SplayTreeNode(SplayTreeNode < E > parent,E key) {
super (key);
this .parent = parent;
}
}
@Override
public boolean delete(E ele) {
return _delete((SplayTreeNode < E > )root,ele);
}
private boolean _delete(SplayTreeNode < E > pointer, E ele) {
int cmp = ele.compareTo(pointer.key);
while (cmp != 0 )
{
if (cmp < 0 )
{
pointer = (SplayTreeNode < E > )pointer.left;
}
else
{
pointer = (SplayTreeNode < E > )pointer.right;
}
if (pointer == null ) return false ;
cmp = ele.compareTo(pointer.key);
}
// okay find it
SplayTreeNode < E > p = pointer.parent;
if (pointer.left == null )
{
if (p != null )
{
keep_right(pointer);
splay(p);
}
else {
root = p.right;
if (root != null )((SplayTreeNode < E > )root).parent = null ;
}
}
else if (pointer.right == null )
{
if (p != null )
{
keep_left(pointer);
splay(p);
}
else {
root = p.left;
if (root != null )((SplayTreeNode < E > )root).parent = null ;
}
}
else
{
SplayTreeNode < E > todo = (SplayTreeNode < E > )pointer.left;
SplayTreeNode < E > todoP = null ;
while (todo.right != null )
{
todoP = todo;
todo = (SplayTreeNode < E > )todo.right;
}
pointer.key = todo.key;
if (todoP != null ) {
todoP.right = todo.left;
if (todo.left != null )
((SplayTreeNode < E > ) todo.left).parent = todoP;
}
else
{
pointer.left = null ;
}
splay(pointer.parent);
}
return true ;
}
private void keep_left(SplayTreeNode < E > pointer) {
SplayTreeNode < E > p = pointer.parent;
if (p.left == pointer)
{
p.left = pointer.left;
if (p.left != null )((SplayTreeNode < E > )p.left).parent = p;
}
else if (p.right == pointer)
{
p.right = pointer.left;
if (p.right != null )((SplayTreeNode < E > )p.right).parent = p;
}
}
private void keep_right(SplayTreeNode < E > pointer) {
SplayTreeNode < E > p = pointer.parent;
if (p.left == pointer)
{
p.left = pointer.right;
if (p.left != null )((SplayTreeNode < E > )p.left).parent = p;
}
else if (p.right == pointer)
{
p.right = pointer.right;
if (p.right != null )((SplayTreeNode < E > )p.right).parent = p;
}
}
protected void splay(SplayTreeNode < E > cur) {
if (cur == null ) return ;
while (cur != root)
{
if (cur.parent == root)
{
// single Rotation
SingleRotation(cur,cur.parent);
cur.parent = null ;
root = cur;
}
else if (cur.parent.left == cur && cur.parent.parent.left == cur.parent)
{
cur = Left_ZigZig(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.right == cur && cur.parent.parent.right == cur.parent)
{
cur = Right_ZigZig(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.left == cur && cur.parent.parent.right == cur.parent)
{
cur = RL_ZigZag(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.right == cur && cur.parent.parent.left == cur.parent)
{
cur = LR_ZigZag(cur,cur.parent,cur.parent.parent);
}
else
{
System.out.println( " Oooops!!! " );
}
}
}
private SplayTreeNode < E > LR_ZigZag(SplayTreeNode < E > cur,
SplayTreeNode < E > p, SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = cur.right;
setParent(cur.right,g);
g.parent = cur;
cur.right = g;
p.right = cur.left;
setParent(cur.left,p);
p.parent = cur;
cur.left = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
private SplayTreeNode < E > RL_ZigZag(SplayTreeNode < E > cur,
SplayTreeNode < E > p, SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = cur.left;
setParent(cur.left,g);
g.parent = cur;
cur.left = g;
p.left = cur.right;
setParent(cur.right,p);
p.parent = cur;
cur.right = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
protected SplayTreeNode < E > Right_ZigZig(SplayTreeNode < E > cur, SplayTreeNode < E > p,
SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = p.left;
setParent(p.left,g);
p.right = cur.left;
setParent(cur.left,p);
g.parent = p;
p.left = g;
p.parent = cur;
cur.left = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
protected SplayTreeNode < E > Left_ZigZig(SplayTreeNode < E > cur, SplayTreeNode < E > p,
SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = p.right;
setParent(p.right,g);
g.parent = p;
p.right = g;
p.left = cur.right;
setParent(cur.right,p);
p.parent = cur;
cur.right = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
final void setParent(BSTNode < E > c, BSTNode < E > p) {
if (c != null )((SplayTreeNode < E > )c).parent = (SplayTreeNode < E > )p;
}
private void SingleRotation(SplayTreeNode < E > cur, SplayTreeNode < E > p) {
if (p.left == cur)
{
p.left = cur.right;
if (cur.right != null )((SplayTreeNode < E > )cur.right).parent = p;
cur.right = p;
p.parent = cur;
}
else if (p.right == cur)
{
p.right = cur.left;
if (cur.left != null )((SplayTreeNode < E > )cur.left).parent = p;
cur.left = p;
p.parent = cur;
}
}
@Override
public void insert(E ele) {
if (root == null ) {
root = new SplayTreeNode < E > ( null ,ele);
return ;
}
_insert((SplayTreeNode < E > )root,ele);
}
private final void _insert(SplayTreeNode < E > pointer,E ele)
{
int cmp = pointer.key.compareTo(ele);
if (cmp == 0 )
{
throw new IllegalArgumentException();
}
if (cmp > 0 )
{
if (pointer.left == null )
{
pointer.left = new SplayTreeNode < E > (pointer,ele);
splay((SplayTreeNode < E > )pointer.left);
return ;
}
_insert((SplayTreeNode < E > )pointer.left,ele);
}
else
{
if (pointer.right == null )
{
pointer.right = new SplayTreeNode < E > (pointer,ele);
splay((SplayTreeNode < E > )pointer.right);
return ;
}
_insert((SplayTreeNode < E > )pointer.right,ele);
}
}
@Override
public boolean search(E ele) {
return _search((SplayTreeNode < E > )root,ele);
}
private boolean _search(SplayTreeNode < E > pointer, E ele) {
if (pointer == null ) return false ;
int cmp = pointer.key.compareTo(ele);
if (cmp == 0 )
{
splay(pointer);
return true ;
}
if (cmp > 0 )
{
return _search((SplayTreeNode < E > )pointer.left,ele);
}
else
{
return _search((SplayTreeNode < E > )pointer.right,ele);
}
}
/**
*
*/
public SplayTree() {
}
}
半伸展树仅仅改变一下一字旋转时的操作:
/**
* @author yovn
*
*/
public class SplayTree < E extends Comparable < E >> extends DefaultBSTree < E > implements BSTree < E > {
static class SplayTreeNode < E extends Comparable < E >> extends BSTNode < E >
{
SplayTreeNode < E > parent;
SplayTreeNode(SplayTreeNode < E > parent,E key) {
super (key);
this .parent = parent;
}
}
@Override
public boolean delete(E ele) {
return _delete((SplayTreeNode < E > )root,ele);
}
private boolean _delete(SplayTreeNode < E > pointer, E ele) {
int cmp = ele.compareTo(pointer.key);
while (cmp != 0 )
{
if (cmp < 0 )
{
pointer = (SplayTreeNode < E > )pointer.left;
}
else
{
pointer = (SplayTreeNode < E > )pointer.right;
}
if (pointer == null ) return false ;
cmp = ele.compareTo(pointer.key);
}
// okay find it
SplayTreeNode < E > p = pointer.parent;
if (pointer.left == null )
{
if (p != null )
{
keep_right(pointer);
splay(p);
}
else {
root = p.right;
if (root != null )((SplayTreeNode < E > )root).parent = null ;
}
}
else if (pointer.right == null )
{
if (p != null )
{
keep_left(pointer);
splay(p);
}
else {
root = p.left;
if (root != null )((SplayTreeNode < E > )root).parent = null ;
}
}
else
{
SplayTreeNode < E > todo = (SplayTreeNode < E > )pointer.left;
SplayTreeNode < E > todoP = null ;
while (todo.right != null )
{
todoP = todo;
todo = (SplayTreeNode < E > )todo.right;
}
pointer.key = todo.key;
if (todoP != null ) {
todoP.right = todo.left;
if (todo.left != null )
((SplayTreeNode < E > ) todo.left).parent = todoP;
}
else
{
pointer.left = null ;
}
splay(pointer.parent);
}
return true ;
}
private void keep_left(SplayTreeNode < E > pointer) {
SplayTreeNode < E > p = pointer.parent;
if (p.left == pointer)
{
p.left = pointer.left;
if (p.left != null )((SplayTreeNode < E > )p.left).parent = p;
}
else if (p.right == pointer)
{
p.right = pointer.left;
if (p.right != null )((SplayTreeNode < E > )p.right).parent = p;
}
}
private void keep_right(SplayTreeNode < E > pointer) {
SplayTreeNode < E > p = pointer.parent;
if (p.left == pointer)
{
p.left = pointer.right;
if (p.left != null )((SplayTreeNode < E > )p.left).parent = p;
}
else if (p.right == pointer)
{
p.right = pointer.right;
if (p.right != null )((SplayTreeNode < E > )p.right).parent = p;
}
}
protected void splay(SplayTreeNode < E > cur) {
if (cur == null ) return ;
while (cur != root)
{
if (cur.parent == root)
{
// single Rotation
SingleRotation(cur,cur.parent);
cur.parent = null ;
root = cur;
}
else if (cur.parent.left == cur && cur.parent.parent.left == cur.parent)
{
cur = Left_ZigZig(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.right == cur && cur.parent.parent.right == cur.parent)
{
cur = Right_ZigZig(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.left == cur && cur.parent.parent.right == cur.parent)
{
cur = RL_ZigZag(cur,cur.parent,cur.parent.parent);
}
else if (cur.parent.right == cur && cur.parent.parent.left == cur.parent)
{
cur = LR_ZigZag(cur,cur.parent,cur.parent.parent);
}
else
{
System.out.println( " Oooops!!! " );
}
}
}
private SplayTreeNode < E > LR_ZigZag(SplayTreeNode < E > cur,
SplayTreeNode < E > p, SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = cur.right;
setParent(cur.right,g);
g.parent = cur;
cur.right = g;
p.right = cur.left;
setParent(cur.left,p);
p.parent = cur;
cur.left = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
private SplayTreeNode < E > RL_ZigZag(SplayTreeNode < E > cur,
SplayTreeNode < E > p, SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = cur.left;
setParent(cur.left,g);
g.parent = cur;
cur.left = g;
p.left = cur.right;
setParent(cur.right,p);
p.parent = cur;
cur.right = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
protected SplayTreeNode < E > Right_ZigZig(SplayTreeNode < E > cur, SplayTreeNode < E > p,
SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = p.left;
setParent(p.left,g);
p.right = cur.left;
setParent(cur.left,p);
g.parent = p;
p.left = g;
p.parent = cur;
cur.left = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
protected SplayTreeNode < E > Left_ZigZig(SplayTreeNode < E > cur, SplayTreeNode < E > p,
SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = p.right;
setParent(p.right,g);
g.parent = p;
p.right = g;
p.left = cur.right;
setParent(cur.right,p);
p.parent = cur;
cur.right = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = cur;
}
else
{
gp.right = cur;
}
}
else root = cur;
cur.parent = gp;
return cur;
}
final void setParent(BSTNode < E > c, BSTNode < E > p) {
if (c != null )((SplayTreeNode < E > )c).parent = (SplayTreeNode < E > )p;
}
private void SingleRotation(SplayTreeNode < E > cur, SplayTreeNode < E > p) {
if (p.left == cur)
{
p.left = cur.right;
if (cur.right != null )((SplayTreeNode < E > )cur.right).parent = p;
cur.right = p;
p.parent = cur;
}
else if (p.right == cur)
{
p.right = cur.left;
if (cur.left != null )((SplayTreeNode < E > )cur.left).parent = p;
cur.left = p;
p.parent = cur;
}
}
@Override
public void insert(E ele) {
if (root == null ) {
root = new SplayTreeNode < E > ( null ,ele);
return ;
}
_insert((SplayTreeNode < E > )root,ele);
}
private final void _insert(SplayTreeNode < E > pointer,E ele)
{
int cmp = pointer.key.compareTo(ele);
if (cmp == 0 )
{
throw new IllegalArgumentException();
}
if (cmp > 0 )
{
if (pointer.left == null )
{
pointer.left = new SplayTreeNode < E > (pointer,ele);
splay((SplayTreeNode < E > )pointer.left);
return ;
}
_insert((SplayTreeNode < E > )pointer.left,ele);
}
else
{
if (pointer.right == null )
{
pointer.right = new SplayTreeNode < E > (pointer,ele);
splay((SplayTreeNode < E > )pointer.right);
return ;
}
_insert((SplayTreeNode < E > )pointer.right,ele);
}
}
@Override
public boolean search(E ele) {
return _search((SplayTreeNode < E > )root,ele);
}
private boolean _search(SplayTreeNode < E > pointer, E ele) {
if (pointer == null ) return false ;
int cmp = pointer.key.compareTo(ele);
if (cmp == 0 )
{
splay(pointer);
return true ;
}
if (cmp > 0 )
{
return _search((SplayTreeNode < E > )pointer.left,ele);
}
else
{
return _search((SplayTreeNode < E > )pointer.right,ele);
}
}
/**
*
*/
public SplayTree() {
}
}
package
algorithms.tree;
/**
* @author yovn
*
*/
public class SemiPlayTree < E extends Comparable < E >> extends SplayTree < E > {
@Override
protected algorithms.tree.SplayTree.SplayTreeNode < E > Left_ZigZig(
algorithms.tree.SplayTree.SplayTreeNode < E > cur,
algorithms.tree.SplayTree.SplayTreeNode < E > p,
algorithms.tree.SplayTree.SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = p.right;
setParent(p.right,g);
p.right = g;
g.parent = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = p;
}
else
{
gp.right = p;
}
}
else root = p;
p.parent = gp;
return p;
}
@Override
protected algorithms.tree.SplayTree.SplayTreeNode < E > Right_ZigZig(
algorithms.tree.SplayTree.SplayTreeNode < E > cur,
algorithms.tree.SplayTree.SplayTreeNode < E > p,
algorithms.tree.SplayTree.SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = p.left;
setParent(p.left,g);
p.left = g;
g.parent = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = p;
}
else
{
gp.right = p;
}
}
else root = p;
p.parent = gp;
return p;
}
}
/**
* @author yovn
*
*/
public class SemiPlayTree < E extends Comparable < E >> extends SplayTree < E > {
@Override
protected algorithms.tree.SplayTree.SplayTreeNode < E > Left_ZigZig(
algorithms.tree.SplayTree.SplayTreeNode < E > cur,
algorithms.tree.SplayTree.SplayTreeNode < E > p,
algorithms.tree.SplayTree.SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.left = p.right;
setParent(p.right,g);
p.right = g;
g.parent = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = p;
}
else
{
gp.right = p;
}
}
else root = p;
p.parent = gp;
return p;
}
@Override
protected algorithms.tree.SplayTree.SplayTreeNode < E > Right_ZigZig(
algorithms.tree.SplayTree.SplayTreeNode < E > cur,
algorithms.tree.SplayTree.SplayTreeNode < E > p,
algorithms.tree.SplayTree.SplayTreeNode < E > g) {
SplayTreeNode < E > gp = g.parent;
g.right = p.left;
setParent(p.left,g);
p.left = g;
g.parent = p;
if (gp != null )
{
if (gp.left == g)
{
gp.left = p;
}
else
{
gp.right = p;
}
}
else root = p;
p.parent = gp;
return p;
}
}