码迷,mamicode.com
首页 > 编程语言 > 详细

平衡二叉树的JAVA版本

时间:2016-05-07 11:02:12      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

伸展树属于一种平衡二叉树。在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。伸展树应运而生。伸展树是一种自调整形式的二叉查找树,它会沿着从某个节点到树根之间的路径,通过一系列的旋转把这个节点搬移到树根去。主要分为四种情况Zig, Zag, Zig-zig, Zig-Zag.

1 Zig-Zig

     技术分享

  2. Zig-Zag

技术分享

代码实现:

package com.lww.tree;



import com.lww.ADT.MyStack;
/**
 * 伸展树的实现
 * @author 黎威威
 *
 * @param <T>
 */
public class SplayTree<T extends Comparable<? super T>> {


/**
* 伸展树结点
* @param <T>
*/
private static class SplayNode<T> {


public SplayNode(T data) {
this(data, null, null);
}


public SplayNode(T data, SplayNode<T> lt, SplayNode<T> rt) {
element = data;
left = lt;
right = rt;
}


T element; // 数据域
SplayNode<T> left; // 左孩子
SplayNode<T> right; // 右孩子
}

private SplayNode<T> root; //树根结点

public SplayTree(){
root=null;
}

/**
* Zig旋转,以左孩子为旋转轴进行旋转
*     1           2
*    / \         / \
*   2   z -->   x   1
*  / \             / \
* x   y           y   z
* @param k2
* @return 返回旋转后子树的根节点
*/
private SplayNode<T> rotateWithLeftChild(SplayNode<T> k1) {
SplayNode<T> k2 = k1.left;
k1.left = k2.right;
k2.right = k1;
return k2;
}
/**
* Zag旋转,以右孩子为旋转轴进行旋转
*     1           2
*    / \         / \
*   z   2 -->   1   y
*      / \     / \   
*     x   y   z   x   
* @param k2
* @return
*/
private SplayNode<T> rotateWithRightChild(SplayNode<T> k1) {
SplayNode<T> k2 = k1.right;
k1.right = k2.left;
k2.left = k1;
return k2;
}
/**
* 左Zig+Zig模型
*         G                  P                  X 
*        / \                / \                / \
*       P   D              X   G              A   P
*      / \    --->        /\   /\    --->        / \
*     X   C              A  B C  D              B   G
*    / \                                           / \
*   A   B                                         C   D
* @param k1
* @return
*/
private SplayNode<T> zigZigWithLeftChild(SplayNode<T> k1){
SplayNode<T> k2=rotateWithLeftChild(k1);
return rotateWithLeftChild(k2);
}

/**
* 右Zig+Zig模型
*     G                  P                  X 
*    / \                / \                / \
*   D   P              G   X               P  B
*      / \    --->    /\   /\       --->  / \
*     C   X          C  D  A B           G   A
*        / \                            / \
*       A   B                          C   D
* @param k1
* @return
*/
private SplayNode<T> zigZigWithRightChild(SplayNode<T> k1){
SplayNode<T> k2=rotateWithRightChild(k1);
return rotateWithRightChild(k2);
}

/**
* 左Zig+Zag模型
*         G                  G                  X 
*        / \                / \                / \
*       P   D              X   D              P   G
*      / \    --->        /\         --->    /\  / \
*     C   X              P  B               C  A B  D
*        / \            / \                             
*       A   B          C   A                             
* @param k1
* @return
*/
private SplayNode<T> zigZagRightRotate(SplayNode<T> k1){
k1.left=rotateWithRightChild(k1.left);
return rotateWithLeftChild(k1);
}

/**
* 右Zig+Zag模型
*     G                  G                  X 
*    / \                / \                / \
*   D   P              D   X              G   P
*      / \    --->        / \       ---> / \  /\
*     X   C               A  P          D   A B C
*    / \                    / \         
*   A   B                  B   C       
* @param k1
* @return
*/
private SplayNode<T> zigZagLeftRotate(SplayNode<T> k1){
k1.right=rotateWithLeftChild(k1.right);
return rotateWithRightChild(k1);
}

/**
* 判断树中是否存在elem元素
* @param elem
* @return
*/
public boolean contains(T elem){

return contains(elem,root);
}
    /**
     * 将elem结点调整至t结点为根结点的子树根结点
     * @param elem
     * @param t
     * @return
     */
private boolean contains(T elem, SplayNode<T> t) {
// TODO Auto-generated method stub
MyStack<SplayNode<T>> stack=new MyStack<>();

while(t!=null){
int compareResult = elem.compareTo(t.element);

if(compareResult<0){
stack.push(t);
t=t.left;
}
else if(compareResult>0){
stack.push(t);
t=t.right;
}
else{
break;
}
}

if(t==null) return false; //没有找到
//伸展操作
root=splay(stack,t);
return true;
}

/**
* 将结点t调整至根部
* @param stack 搜索结点t的路径结点
* @param t
*/
private SplayNode<T> splay(MyStack<SplayNode<T>> stack, SplayNode<T> t){
while(!stack.isEmpty()){
if(stack.size()>=2){
SplayNode<T> k1=stack.pop();
SplayNode<T> k2=stack.pop();
if(!stack.isEmpty())
{  
if(stack.getTop().left == k2)
stack.getTop().left=t;
else
stack.getTop().right=t;
}
if(k1==k2.left){
if(t==k1.left){
//TODO:左Zig-zig模型
zigZigWithLeftChild(k2);
}
else{
//TODO:左Zig-zag模型
zigZagRightRotate(k2);
}
}
else if(k1==k2.right){
if(t==k1.right){
//TODO:右Zig-zig模型
zigZigWithRightChild(k2);
}
else{
//TODO:左Zig-zag模型
zigZagLeftRotate(k2);
}
}
}
else{


SplayNode<T> k1=stack.pop();
if(t==k1.left){
//TODO:Zig模型
rotateWithLeftChild(k1);
}
else{
//TODO:Zag模型
rotateWithRightChild(k1);
}
}
}
return t;
}

public boolean insert(T x){
root=insert(x,root);
contains(x,root); //将调整至root
return true;
}

public SplayNode<T> insert(T element,SplayNode<T> k1){
if(k1==null) return new SplayNode<T>(element);
int compareResult=element.compareTo(k1.element);

if(compareResult<0)
k1.left=insert(element,k1.left);
else if(compareResult>0)
k1.right=insert(element,k1.right);
else
;//Duplicate; Do nothing
return k1;
}

public boolean Remove(T x) {
if (contains(x, root)) {
/**
* 此时X就是根结点
*/
SplayNode<T> k1 = root.left, k2 = root.right;
if (k1 != null) {
root=findMax(k1);
root.right=k2;
} else
root = k2;
return true;
} else
return false;
}
/**
* 寻找最大的结点
* @return
*/
public T findMax(){
root=findMax(root);
return root!=null? root.element:null;
}

/**
* 寻找以t为根的子树最大元素
* @param t
* @return
*/
private SplayNode<T> findMax(SplayNode<T> t) {
// TODO Auto-generated method stub
if(t==null) return null;
MyStack<SplayNode<T>> stack=new MyStack<>();
while (t.right!= null) {
stack.push(t);
t=t.right;
}
t=splay(stack,t);
return t;
}

/**
* 寻找最小的结点
* @return
*/
public T findMin(){
root=findMin(root);
return root!=null? root.element:null;
}

/**
* 寻找以t为根的子树最大元素
* @param t
* @return
*/
private SplayNode<T> findMin(SplayNode<T> t) {
// TODO Auto-generated method stub
if(t==null) return null;
MyStack<SplayNode<T>> stack=new MyStack<>();
while (t.left!= null) {
stack.push(t);
t=t.left;
}
t=splay(stack,t);
return t;
}


/**
* 非递归前序遍历
*/
public void preOrderPrint(){
MyStack<SplayNode<T>> stack=new MyStack<>();
if(root==null) return;
/*版本一
* AvlNode<T> t=null;
stack.push(root);
while(!stack.isEmpty()){
  t=stack.pop();
  System.out.print(t.element+":");
  System.out.print(t.left!=null?t.left.element+" , ":"NULL"+" , ");
  System.out.print(t.right!=null?t.right.element:"NULL");
  System.out.println();
  if(t.right!=null) stack.push(t.right);
  if(t.left!=null) stack.push(t.left);
}*/

/**版本二**/
while(root!=null){
System.out.print(root.element + ":");
System.out.print(root.left != null ? root.left.element + " , " : "NULL" + " , ");
System.out.print(root.right != null ? root.right.element : "NULL");
System.out.println();
stack.push(root);
root=root.left;
}
SplayNode<T> t = null;
while (!stack.isEmpty()) {
t = stack.pop();
if(t.right!=null){
SplayNode<T> t0=t.right;
while(t0!=null){
System.out.print(t0.element + ":");
System.out.print(t0.left != null ? t0.left.element + " , " : "NULL" + " , ");
System.out.print(t0.right != null ? t0.right.element : "NULL");
System.out.println();
stack.push(t0);
t0=t0.left;
}
}
}
}
public static void main(String[] args){
SplayTree<Integer> tree=new SplayTree();
for(int i=3;i<=10000;i=i+2){
tree.insert(i);
tree.insert(i-1);
}
tree.insert(32);
tree.insert(1);
  for(int i=2;i<=10000;i++)
  tree.contains(i);
tree.preOrderPrint();
}
}

平衡二叉树的JAVA版本

标签:

原文地址:http://blog.csdn.net/a1548178885/article/details/51333282

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!