Treap(树堆)

Treap=Tree+Heap。Treap本身是一棵 二叉搜索树 ,它的左子树和右子树也分别是一个Treap,和一般的 二叉搜索树 不同的是,Treap记录一个额外的数据,就是优先级。Treap在以关键码构成 二叉搜索树 的同时,还按优先级来满足 的性质(在这里我们假设节点的优先级大于该节点的孩子的优先级)。但是这里要注意的是Treap和二叉堆有一点不同,就是二叉堆必须是完全二叉树,而Treap可以并不一定是。

旋转说明:
" 如果当前节点的优先级比父节点的优先级的值大就旋转,如果当前节点是根的左儿子就右旋如果当前节点是根的右儿子就左旋。 "

右旋转
结点右旋 :node x, y=x->left;  先将 y 的右子树作为 x 的左子树 , 然后将 x 作为 y 的右子树 最后将 y 作为 x 原父结点的子树 ( x 为左子树 , 此时 y 仍然为左子树 ,x 为右子树 ,y 也为右子树 )

左旋转:
结点左旋 : 父节点node x, y=x->right;  先将 y 的左子树作为 x 的右子树 , 然后将 x 作为 y 的左子树 最后将 y 作为 x 原父结点的子树 ( x 为左子树 , 此时 y 仍然为左子树 ,x 为右子树 ,y 也为右子树 ) 如下图所示 .



完整的Java代码实现如下:
import  java.util.ArrayList;
import  java.util.LinkedList;
import  java.util.List;
import  java.util.Random;
import  java.util.concurrent.Callable;
import  java.util.concurrent.ExecutionException;
import  java.util.concurrent.ExecutorService;
import  java.util.concurrent.Executors;
import  java.util.concurrent.Future;
import  java.util.concurrent.FutureTask;
import  java.util.concurrent.locks.ReentrantLock;

/**
 * 随机二叉树的 Java代码实现
 * 
 * 
@author  xiemalin
 * 
 
*/
public   class  Treap < extends  Comparable < K >>   extends  ReentrantLock {

    
private  Node root;

    
public   void  insert(K key,  float  fix) {
        
try  {
            Node node 
=   new  Node(key, fix);
            lock();
            
if  (root  ==   null ) {
                root 
=  node;
                
return ;
            }

            insert(root, node);
        } 
finally  {
            unlock();
        }

    }

    
private   void  insert(Node root, Node node) {
        K key 
=  node.key;
        
int  compare  =  key.compareTo(root.key);
        
if  (compare  <   0 ) {
            
if  (root.left  ==   null ) {
                root.left 
=   new  Node(node.key, node.fix);
            } 
else  {
                insert(root.left, node);
            }
            
if  (root.left.fix  >  root.fix) {
                rotateRight(root);
            }
        } 
else   if  (compare  >   0 ) {
            
if  (root.right  ==   null ) {
                root.right 
=   new  Node(node.key, node.fix);
            } 
else  {
                insert(root.right, node);
            }
            
if  (root.right.fix  >  root.fix) {
                rotateLeft(root);
            }
        } 
else  {
            
// key exist do replace
            
root.fix = node.fix;
        }
    }

    
public  Node remove(K key) {
        
try  {
            lock();
            
return  remove(root, key);
        } 
finally  {
            unlock();
            
        }
    }

    
public  Node remove(Node root, K key) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
int  compare  =  key.compareTo(root.key);
        
if  (compare  <   0 ) {
            
return  remove(root.left, key);
        } 
else   if  (compare  >   0 ) {
            
return  remove(root.right, key);
        } 
else  {
            
if  (root.left  ==   null   &&  root.right  ==   null ) {
                swapLocatePoint(root, 
null );
                
return  root;
            } 
else   if  (root.left  ==   null ) {
                swapLocatePoint(root, root.right);
                
return  root;
            } 
else   if  (root.right  ==   null ) {
                swapLocatePoint(root, root.left);
                
return  root;
            } 
else  {
                
//  has left and right node
                 if  (root.left.fix  <  root.right.fix) {
                    rotateLeft(root);
                    root 
=  find(root.key);
                    
return  remove(root, key);
                } 
else  {
                    rotateRight(root);
                    root 
=  find(root.key);
                    
return  remove(root, key);
                }
            }
        }
    }
    
    
public  Node find(K key) {
        
return  find(root, key);
    }
    
    
public  Node find(Node root, K key) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
int  compare  =  key.compareTo(root.key);
        
if  (compare  ==   0 ) {
            
return  root;
        } 
else  {
            
if  (compare  <   0 ) {
                
return  find(root.left, key);
            } 
else  {
                
return  find(root.right, key);
            }
        }
    }
    
    
public  Node findParent(Node root, K key, Node parent) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
int  compare  =  key.compareTo(root.key);
        
if  (compare  ==   0 ) {
            
return  parent;
        } 
else  {
            
if  (compare  <   0 ) {
                
return  findParent(root.left, key, root);
            } 
else  {
                
return  findParent(root.right, key, root);
            }
        }
        
        
    }

    
/**
     *   a 
     *    \ 
     *     x 
     *    / \ 
     *   nll y
     * 
     * 左转之后的结果 
     *    a 
     *     \ 
     *      y 
     *     / \ 
     *   x null 
     *    \ 
     *  (y.left=null)
     * 
     * 
@param  x
     
*/
    
private   void  rotateLeft(Node x) { //  rotate to left on node x  // 左旋当前节点
        Node y  =  x.right;  //  把当前节点的右节点,复制给y
        x.right  =  y.left;  //  把当前节点的右节点的左子树复制给当前节点
        y.left  =  x;  //
        swapLocatePoint(x, y);
    }

    
private   void  swapLocatePoint(Node x, Node y) {
        Node parent 
=  findParent(root, x.key,  null );
        
if  (parent  ==   null ) {
            root 
=  y;
            
return ;
        }
        
if  (parent.left  ==  x) {
            parent.left 
=  y;
        } 
else  {
            parent.right 
=  y;
        }
    }
    
    
    
public  String toString() {
        
if  (root  ==   null ) {
            
return   "" ;
        }
        
        StringBuffer buffer 
=   new  StringBuffer( 200 );
        flat(buffer, root);
        
return  buffer.toString();
    }
    
    
public   void  flat(StringBuffer buffer, Node nodes) {
        buffer.append(
" \n " );
        
if  (nodes  !=   null   &&  nodes.length  >   0 ) {
            List
< Node >  list  =   new  LinkedList < Node > ();
            
boolean  hasValue  =   false ;
            
for  (Node node : nodes) {
                buffer.append(node).append(
" | " );
                
if  (node.left  !=   null ) {
                    list.add(node.left);
                    hasValue 
=   true ;
                } 
else  {
                    list.add(
new  EmptyNode());
                }
                
if  (node.right  !=   null ) {
                    list.add(node.right);
                    hasValue 
=   true ;
                } 
else  {
                    list.add(
new  EmptyNode());
                }
            }
            buffer 
=  buffer.deleteCharAt(buffer.length()  -   1 );
            
if  (hasValue) {
                flat(buffer, list.toArray(
new  Treap.Node[list.size()]));
            }
            
        }
    }
    

    
/**
     *    a 
     *     \ 
     *      x 
     *     / \ 
     *    y null
     * 
     * 右转之后的结果 
     *    a 
     *     \ 
     *      y 
     *     / \ 
     *   null x 
     *       / 
     *   (y.right=null)
     * 
     * 
@param  x
     
*/
    
private   void  rotateRight(Node x) { //  rotate to right on node x
        Node y  =  x.left;
        x.left 
=  y.right;
        y.right 
=  x;
        swapLocatePoint(x, y);
    }

    
public   static   void  main(String[] args) {
        Treap
< Float >  t  =   new  Treap < Float > ();

        t.insert(
9.5f 0.491f );
        t.insert(
8.3f 0.491f );
        t.insert(10f, 
0.971f );
        t.insert(
10.25f 0.882f );
        System.out.println(t);
        
        
// System.out.println(t.remove(10));
        t.remove(10f);
        
        System.out.println(t);
        
        
        
final  Treap t2  =   new  Treap();
        t2.insert(
9.0f 0.554f );
        t2.insert(
8.0f 0.701f );
        t2.insert(
12.5f 0.516f );
        t2.insert(
7.0f 0.141f );
        t2.insert(
4.0f 0.340f );
        t2.insert(
2.0f 0.286f );
        t2.insert(
3.0f 0.402f );
        t2.insert(
1.0f 0.646f );
        t2.insert(
5.0f 0.629f );
        t2.insert(
10.0f 0.244f );
        t2.insert(
11.0f 0.467f );
        t2.insert(
12.0f 0.794f );
        t2.insert(
13.0f 0.667f );
        t2.insert(
6.0f 0.375f );
        
        System.out.println(t2);
        
final  Random r  =   new  Random();
        


        
        
long  time  =  System.currentTimeMillis();
        
        ExecutorService es 
=  Executors.newFixedThreadPool( 3 );
        List
< Future >  futures  =   new  ArrayList < Future > ( 3 );
        
for  ( int  i  =   0 ; i  <   3 ; i ++ ) {
            
            FutureTask
< String >  future  =
                
new  FutureTask < String > ( new  Callable < String > () {
                  
public  String call() {
                      
for  ( int  i  =   0 ; i  <   200000 ; i ++ ) {
                          t2.insert(r.nextFloat(), r.nextFloat());
                      }
                      
return   null ;
                }});
            
            es.execute(future);
            futures.add(future);
        }
        
        
for  (Future future : futures) {
            
try  {
                future.get();
            } 
catch  (InterruptedException e) {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            } 
catch  (ExecutionException e) {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        System.out.println(
" time took: "   +  (System.currentTimeMillis()  -  time));
        time 
=  System.currentTimeMillis();
        System.out.println(t2.find(
6.0f ));
        System.out.println(
" time took: "   +  (System.currentTimeMillis()  -  time));
        
        es.shutdown();
        
        
        Treap
< String >  t3  =   new  Treap < String > ();
        
        t3.insert(
" abc " , 222f);
        t3.insert(
" ad " , 222f);
        t3.insert(
" fbc " , 222f);
        t3.insert(
" adbc " , 222f);
        t3.insert(
" bbc " , 222f);
        
        System.out.println(t3.find(
" bbc " ));
    }
    
    
class  Node {
        K key;
        
float  fix;
        Node left;
        Node right;
        
        
public  Node() {
            
        }

        
/**
         * 
@param  key
         * 
@param  fix
         
*/
        
public  Node(K key,  float  fix) {
            
super ();
            
this .key  =  key;
            
this .fix  =  fix;
        }
        
        
public  String toString() {
            
return  key + "" ;
        }
    }

    
class  EmptyNode  extends  Node {
        
public  String toString() {
            
return   " NULL " ;
        }
    }

}


非泛型实现
import  java.util.ArrayList;
import  java.util.LinkedList;
import  java.util.List;
import  java.util.Random;
import  java.util.concurrent.Callable;
import  java.util.concurrent.ExecutionException;
import  java.util.concurrent.ExecutorService;
import  java.util.concurrent.Executors;
import  java.util.concurrent.Future;
import  java.util.concurrent.FutureTask;
import  java.util.concurrent.locks.ReentrantLock;

/**
 * 随机二叉树的 Java代码实现
 * 
 * 
@author  xiemalin
 * 
 
*/
public   class  Treap  extends  ReentrantLock {

    
private  Node root;

    
public   void  insert( float  key,  float  fix) {
        
try  {
            Node node 
=   new  Node(key, fix);
            lock();
            
if  (root  ==   null ) {
                root 
=  node;
                
return ;
            }

            insert(root, node);
        } 
finally  {
            unlock();
        }
    }
    
    
public   void  set( float  key,  float  fix) {
        
try  {
            Node node 
=   new  Node(key, fix);
            lock();
            
if  (root  ==   null ) {
                root 
=  node;
                
return ;
            }
            
try  {
                insert(root, node);
            } 
catch  (KeyExistException e) {
                remove(root, key);
                insert(root, node);
            }
            
        } 
finally  {
            unlock();
        }
    }

    
private   void  insert(Node root, Node node) {
        
float  key  =  node.key;
        
if  (key  <  root.key) {
            
if  (root.left  ==   null ) {
                root.left 
=   new  Node(node.key, node.fix);
            } 
else  {
                insert(root.left, node);
            }
            
if  (root.left.fix  >  root.fix) {
                rotateRight(root);
            }
        } 
else   if  (key  >  root.key) {
            
if  (root.right  ==   null ) {
                root.right 
=   new  Node(node.key, node.fix);
            } 
else  {
                insert(root.right, node);
            }
            
if  (root.right.fix  >  root.fix) {
                rotateLeft(root);
            }
        } 
else  {
            
// key exist ignore
             throw   new  KeyExistException( " key= "   +  key  +   "  already exist " );
            
// root.fix = node.fix;
        }
    }

    
public  Node remove( float  key) {
        
try  {
            lock();
            
return  remove(root, key);
        } 
finally  {
            unlock();
            
        }
    }

    
public  Node remove(Node root,  float  key) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
if  (key  <  root.key) {
            
return  remove(root.left, key);
        } 
else   if  (key  >  root.key) {
            
return  remove(root.right, key);
        } 
else  {
            
if  (root.left  ==   null   &&  root.right  ==   null ) {
                swapLocatePoint(root, 
null );
                
return  root;
            } 
else   if  (root.left  ==   null ) {
                swapLocatePoint(root, root.right);
                
return  root;
            } 
else   if  (root.right  ==   null ) {
                swapLocatePoint(root, root.left);
                
return  root;
            } 
else  {
                
//  has left and right node
                 if  (root.left.fix  <  root.right.fix) {
                    rotateLeft(root);
                    root 
=  find(root.key);
                    
return  remove(root, key);
                } 
else  {
                    rotateRight(root);
                    root 
=  find(root.key);
                    
return  remove(root, key);
                }
            }
        }
    }
    
    
public  Node find( float  key) {
        
return  find(root, key);
    }
    
    
public  Node find(Node root,  float  key) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
if  (key  ==  root.key) {
            
return  root;
        } 
else  {
            
if  (key  <  root.key) {
                
return  find(root.left, key);
            } 
else  {
                
return  find(root.right, key);
            }
        }
    }
    
    
public  Node findParent(Node root,  float  key, Node parent) {
        
if  (root  ==   null ) {
            
return   null ;
        }
        
if  (key  ==  root.key) {
            
return  parent;
        } 
else  {
            
if  (key  <  root.key) {
                
return  findParent(root.left, key, root);
            } 
else  {
                
return  findParent(root.right, key, root);
            }
        }
        
        
    }

    
/**
     *   a 
     *    \ 
     *     x 
     *    / \ 
     *   nll y
     * 
     * 左转之后的结果 
     *    a 
     *     \ 
     *      y 
     *     / \ 
     *   x null 
     *    \ 
     *  (y.left=null)
     * 
     * 
@param  x
     
*/
    
private   void  rotateLeft(Node x) { //  rotate to left on node x  // 左旋当前节点
        Node y  =  x.right;  //  把当前节点的右节点,复制给y
        x.right  =  y.left;  //  把当前节点的右节点的左子树复制给当前节点
        y.left  =  x;  //
        swapLocatePoint(x, y);
    }

    
private   void  swapLocatePoint(Node x, Node y) {
        Node parent 
=  findParent(root, x.key,  null );
        
if  (parent  ==   null ) {
            root 
=  y;
            
return ;
        }
        
if  (parent.left  ==  x) {
            parent.left 
=  y;
        } 
else  {
            parent.right 
=  y;
        }
    }
    
    
    
public  String toString() {
        
if  (root  ==   null ) {
            
return   "" ;
        }
        
        StringBuffer buffer 
=   new  StringBuffer( 200 );
        flat(buffer, root);
        
return  buffer.toString();
    }
    
    
public   void  flat(StringBuffer buffer, Node nodes) {
        buffer.append(
" \n " );
        
if  (nodes  !=   null   &&  nodes.length  >   0 ) {
            List
< Node >  list  =   new  LinkedList < Node > ();
            
boolean  hasValue  =   false ;
            
for  (Node node : nodes) {
                buffer.append(node).append(
" | " );
                
if  (node.left  !=   null ) {
                    list.add(node.left);
                    hasValue 
=   true ;
                } 
else  {
                    list.add(
new  EmptyNode());
                }
                
if  (node.right  !=   null ) {
                    list.add(node.right);
                    hasValue 
=   true ;
                } 
else  {
                    list.add(
new  EmptyNode());
                }
            }
            buffer 
=  buffer.deleteCharAt(buffer.length()  -   1 );
            
if  (hasValue) {
                flat(buffer, list.toArray(
new  Treap.Node[list.size()]));
            }
            
        }
    }
    

    
/**
     *    a 
     *     \ 
     *      x 
     *     / \ 
     *    y null
     * 
     * 右转之后的结果 
     *    a 
     *     \ 
     *      y 
     *     / \ 
     *   null x 
     *       / 
     *   (y.right=null)
     * 
     * 
@param  x
     
*/
    
private   void  rotateRight(Node x) { //  rotate to right on node x
        Node y  =  x.left;
        x.left 
=  y.right;
        y.right 
=  x;
        swapLocatePoint(x, y);
    }

    
public   static   void  main(String[] args) {
        Treap t 
=   new  Treap();

        t.insert(
0.0f 0.845f );
        System.out.println(t);
        t.insert(
0.5f 0.763f );
        System.out.println(t);
        t.insert(
0.25f 0.244f );
        System.out.println(t);
        t.insert(
1.0f 0.347f );
        System.out.println(t);
        t.insert(
1.25f 0.925f );
        System.out.println(t);
        
        
// System.out.println(t.remove(10));
        t.remove(10f);
        
        System.out.println(t);
        
        
        
final  Treap t2  =   new  Treap();
        t2.insert(
9.0f 0.554f );
        t2.insert(
8.0f 0.701f );
        t2.insert(
12.5f 0.516f );
        t2.insert(
7.0f 0.141f );
        t2.insert(
4.0f 0.340f );
        t2.insert(
2.0f 0.286f );
        t2.insert(
3.0f 0.402f );
        t2.insert(
1.0f 0.646f );
        t2.insert(
5.0f 0.629f );
        t2.insert(
10.0f 0.244f );
        t2.insert(
11.0f 0.467f );
        t2.insert(
12.0f 0.794f );
        t2.insert(
13.0f 0.667f );
        t2.insert(
6.0f 0.375f );
        
        System.out.println(t2);
        
final  Random r  =   new  Random();
        


        
        
long  time  =  System.currentTimeMillis();
        
        ExecutorService es 
=  Executors.newFixedThreadPool( 3 );
        List
< Future >  futures  =   new  ArrayList < Future > ( 3 );
        
for  ( int  i  =   0 ; i  <   3 ; i ++ ) {
            
            FutureTask
< String >  future  =
                
new  FutureTask < String > ( new  Callable < String > () {
                  
public  String call() {
                      
for  ( int  i  =   0 ; i  <   1000000 ; i ++ ) {
                          t2.set(r.nextFloat(), r.nextFloat());
                      }
                      
return   null ;
                }});
            
            es.execute(future);
            futures.add(future);
        }
        
        
for  (Future future : futures) {
            
try  {
                future.get();
            } 
catch  (InterruptedException e) {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            } 
catch  (ExecutionException e) {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        System.out.println(
" time took: "   +  (System.currentTimeMillis()  -  time));
        time 
=  System.currentTimeMillis();
        System.out.println(t2.find(
6.0f ));
        System.out.println(
" time took: "   +  (System.currentTimeMillis()  -  time));
        
        es.shutdown();
        

    }
    
    
class  Node {
        
float  key;
        
float  fix;
        Node left;
        Node right;
        
        
public  Node() {
            
        }

        
/**
         * 
@param  key
         * 
@param  fix
         
*/
        
public  Node( float  key,  float  fix) {
            
super ();
            
this .key  =  key;
            
this .fix  =  fix;
        }
        
        
public  String toString() {
            
return  key + "" ;
        }
    }

    
class  EmptyNode  extends  Node {
        
public  String toString() {
            
return   " NULL " ;
        }
    }

}


参考资料:
DEMO示例 http://www.ibr.cs.tu-bs.de/courses/ss98/audii/applets/BST/Treap-Example.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值