splay tree java移除_伸展树(三)之 Java的实现

概要

前面分别通过C和C++实现了伸展树,本章给出伸展树的Java版本。基本算法和原理都与前两章一样。

1.2.3.

伸展树的介绍

伸展树(Splay Tree)是特殊的二叉查找树。

它的特殊是指,它除了本身是棵二叉查找树之外,它还具备一个特点: 当某个节点被访问时,伸展树会通过旋转使该节点成为树根。这样做的好处是,下次要访问该节点时,能够迅速的访问到该节点。

伸展树的Java实现

1. 基本定义

public class SplayTree>{private SplayTreeNode mRoot; //根结点

public class SplayTreeNode>{

T key;//关键字(键值)

SplayTreeNode left; //左孩子

SplayTreeNode right; //右孩子

publicSplayTreeNode() {this.left = null;this.right = null;

}public SplayTreeNode(T key, SplayTreeNode left, SplayTreeNoderight) {this.key =key;this.left =left;this.right =right;

}

}

...

}

SplayTree是伸展树,而SplayTreeNode是伸展树节点。在此,我将SplayTreeNode定义为SplayTree的内部类。在伸展树SplayTree中包含了伸展树的根节点mRoot。SplayTreeNode包括的几个组成元素:

(01) key -- 是关键字,是用来对伸展树的节点进行排序的。

(02) left -- 是左孩子。

(03) right -- 是右孩子。

2. 旋转

旋转是伸展树中需要重点关注的,它的代码如下:

/** 旋转key对应的节点为根节点,并返回根节点。

*

* 注意:

* (a):伸展树中存在"键值为key的节点"。

* 将"键值为key的节点"旋转为根节点。

* (b):伸展树中不存在"键值为key的节点",并且key < tree.key。

* b-1 "键值为key的节点"的前驱节点存在的话,将"键值为key的节点"的前驱节点旋转为根节点。

* b-2 "键值为key的节点"的前驱节点存在的话,则意味着,key比树中任何键值都小,那么此时,将最小节点旋转为根节点。

* (c):伸展树中不存在"键值为key的节点",并且key > tree.key。

* c-1 "键值为key的节点"的后继节点存在的话,将"键值为key的节点"的后继节点旋转为根节点。

* c-2 "键值为key的节点"的后继节点不存在的话,则意味着,key比树中任何键值都大,那么此时,将最大节点旋转为根节点。*/

private SplayTreeNode splay(SplayTreeNodetree, T key) {if (tree == null)returntree;

SplayTreeNode N = new SplayTreeNode();

SplayTreeNode l =N;

SplayTreeNode r =N;

SplayTreeNodec;for(;;) {int cmp =key.compareTo(tree.key);if (cmp < 0) {if (tree.left == null)break;if (key.compareTo(tree.left.key) < 0) {

c= tree.left; /*rotate right*/tree.left=c.right;

c.right=tree;

tree=c;if (tree.left == null)break;

}

r.left= tree; /*link right*/r=tree;

tree=tree.left;

}else if (cmp > 0) {if (tree.right == null)break;if (key.compareTo(tree.right.key) > 0) {

c= tree.right; /*rotate left*/tree.right=c.left;

c.left=tree;

tree=c;if (tree.right == null)break;

}

l.right= tree; /*link left*/l=tree;

tree=tree.right;

}else{break;

}

}

l.right= tree.left; /*assemble*/r.left=tree.right;

tree.left=N.right;

tree.right=N.left;returntree;

}public voidsplay(T key) {

mRoot=splay(mRoot, key);

}

上面的代码的作用:将"键值为key的节点"旋转为根节点,并返回根节点。它的处理情况共包括:

(a):伸展树中存在"键值为key的节点"。

将"键值为key的节点"旋转为根节点。

(b):伸展树中不存在"键值为key的节点",并且key < tree->key。

b-1) "键值为key的节点"的前驱节点存在的话,将"键值为key的节点"的前驱节点旋转为根节点。

b-2) "键值为key的节点"的前驱节点存在的话,则意味着,key比树中任何键值都小,那么此时,将最小节点旋转为根节点。

(c):伸展树中不存在"键值为key的节点",并且key > tree->key。

c-1) "键值为key的节点"的后继节点存在的话,将"键值为key的节点"的后继节点旋转为根节点。

c-2) "键值为key的节点"的后继节点不存在的话,则意味着,key比树中任何键值都大,那么此时,将最大节点旋转为根节点。

下面列举个例子分别对a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值