Treap树结构

        Treap,是有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。其基本操作的期望时间复杂度为O(logn)。相对于其他的平衡二叉搜索树,Treap的特点是实现简单,且能基本实现随机平衡的结构

        Treap=Tree+Heap。Treap本身是一棵二叉搜索树,它的左子树和右子树也分别是一个Treap,和一般的二叉搜索树不同的是,Treap纪录一个额外的数据,就是优先级。Treap在以关键码构成二叉搜索树的同时,还满足堆的性质。Treap维护堆性质的方法用到了旋转,只需要两种旋转,编程复杂度比Splay要小一些。

插入

        给节点随机分配一个优先级,先和二叉搜索树的插入一样,先把要插入的点插入到一个叶子上,然后跟维护堆一样,如果当前节点的优先级比根大就旋转,如果当前节点是根的左儿子就右旋如果当前节点是根的右儿子就左旋。

由于旋转是O(1)的,最多进行h次(h是树的高度),插入的复杂度是O(h)的,在期望情况下h=O(logn),所以它的期望复杂度是O(logn)。

删除

        因为Treap满足堆性质,所以只需要把要删除的节点旋转到叶节点上,然后直接删除就可以了。具体的方法就是每次找到优先级最大的儿子,向与其相反的方向旋转,直到那个节点被旋转到了叶节点,然后直接删除。

删除最多进行O(h)次旋转,期望复杂度是O(logn)。

查询

        和一般的二叉搜索树一样,但是由于Treap的随机化结构,Treap中查找的期望复杂度是O(logn)。

代码(一种递归实现):

#include <iostream>
#include <iomanip>
#include <queue>
#include <cstdlib>
using namespace std;

typedef struct TreapNode * Treap;
typedef struct TreapNode
{
	int data;
	int priority;
	Treap lchild,rchild;
} TreapNode; 
#define Infinity 0x7FFFFFFF
Treap NullNode = NULL;

Treap Initialize(void)
{
	if (NullNode == NULL) 
	{
		NullNode = new TreapNode;
		NullNode->priority = Infinity;
		NullNode->lchild = NullNode->rchild = NullNode; 	
	}
	return NullNode;
}

Treap SingleRotateWithLeft(Treap x)
{
	Treap y = x->lchild;
	x->lchild = y->rchild;
	y->rchild = x;
	return y;
}
Treap SingleRotateWithRight(Treap x)
{
	Treap y = x->rchild;
	x->rchild = y->lchild;
	y->lchild = x;
	return y;
}
Treap insert(int key, Treap T)
{
	if (T == NullNode) {
		/* create and return an one-node tree */
		T = new TreapNode;
		T->data = key;
		T->priority = rand();
		T->lchild = T->rchild = NullNode; 
	}
	else
	{
		if (key < T->data) {
			T->lchild = insert(key, T->lchild);
			if (T->lchild->priority < T->priority) {
				T = SingleRotateWithLeft(T);
			}
		}
		else if (key > T->data) {
			T->rchild = insert(key,T->rchild);
			if (T->rchild->priority < T->priority) {
				T = SingleRotateWithRight(T);
			}
		}
		
	}
	return T;
}

Treap remove(int key, Treap T)
{
	if (T != NullNode) 
	{
		if (key < T->data) {
			T->lchild = remove(key,T->lchild);		
		}	
		else if (key > T->data) {
			T->rchild = remove(key,T->rchild); 
		}
		else {
			/*match found*/
			if (T->lchild->priority < T->rchild->priority)
				T = SingleRotateWithLeft(T);
			else 
				T = SingleRotateWithRight(T);
				
			if (T != NullNode) /* continue go down*/
				T = remove(key,T);
			else
			{
				/* at a leaf*/
				delete (T->lchild);
				T->lchild = NullNode;
			} 
		}
	}
	return T;
}

/*------------------about tree display -----------------------------------------*/
inline int max(int a,int b)
{
	return a>b?a:b;
}
int Height(Treap T)
{
	if (T == NullNode)
		return 0;
	else
		return 1 + max(Height(T->lchild), Height(T->rchild));
}
void MakeMat(Treap T,int root_x,int root_y,int step,int **m)
{
	int lChildPos,rChildPos;
	lChildPos = root_x - step;
	rChildPos = root_x + step;
	if (T == NullNode) 
		return;
	else
	{
		m[root_y][root_x] = 1;
		MakeMat(T->lchild,lChildPos,root_y+1,step>>1,m);
		MakeMat(T->rchild,rChildPos,root_y+1,step>>1,m);
	}
}

void TreapDisplay(Treap T)
{
	if(T == NullNode)
		return;
	/* init placehold flags m[h][len] */
	int h = Height(T);
	int len = (1<<h) - 1;
	int row = h; 
	int **m = new int*[row];
	for(int i= 0;i<row;i++){
		m[i] = new int[len];
		memset(m[i],0,len*sizeof(int));	
	}
	/* get level order traversal sequence */
	vector<Treap> v;
	queue<Treap> q;
	queue<Treap> qt;
	q.push(T);
	Treap pt;
	while(!q.empty())
	{
		pt = q.front();
		if (pt->lchild != NullNode)
			q.push(pt->lchild);
		if(pt->rchild != NullNode)
			q.push(pt->rchild);
		v.push_back(pt);		
		q.pop();
	}
	/* generate output matrix  plus '/' and '\\' m[2*h-1][len] */
	MakeMat(T,len>>1,0,len+1>>2,m);
	/* generate output */
	int cnt = 0;
	int width = 1;
	for(int i = 0; i < row; i++)
	{
		for(int j = 0; j < len; j++)
		{
			if(m[i][j])
			{
//				if (i & 1) 
//					cout<<setw(width)<<char(m[i][j]);
//				else
//					cout<<setw(width)<<char(m[i][j]);
//					cout<<setw(width)<<m[i][j];
				cout<<(v[cnt])->data;
				cnt++;
			}
			else
				cout<<setw(width)<<' ';		
		}
		cout<<endl;
	}
	
}

/*-------------- I am a cut-----------------------------------------------------*/
int main()
{
	NullNode = Initialize();
	Treap T = NullNode;
	int i;
	for (i = 1; i <= 7 ; i++) 
	{
		cout<<"Key = "<<i<<" inserting :"<<endl;
		T = insert(i,T);
		TreapDisplay(T);
		cout<<"------------------------------------------"
		"--------------------------"<<endl; 
	}
	for( i = 1;i <= 7; i++)
	{
		cout<<"Key = "<<i<<" deleting :"<<endl;
		T = remove(i,T);
		TreapDisplay(T);
		cout<<"------------------------------------------"
		"--------------------------"<<endl; 
	}
	
}

代码输出:

Key = 1 inserting :
1
--------------------------------------------------------------------
Key = 2 inserting :
 1 
  2
--------------------------------------------------------------------
Key = 3 inserting :
   1   
     3 
    2  
--------------------------------------------------------------------
Key = 4 inserting :
   1   
     3 
    2 4
--------------------------------------------------------------------
Key = 5 inserting :
       1       
           3   
         2   5 
            4  
--------------------------------------------------------------------
Key = 6 inserting :
               1               
                       3       
                   2       6   
                         5     
                        4      
--------------------------------------------------------------------
Key = 7 inserting :
                               1                               
                                               3               
                                       2               7       
                                                   6           
                                                 5             
                                                4              
--------------------------------------------------------------------
Key = 1 deleting :
               3               
       2               7       
                   6           
                 5             
                4              
--------------------------------------------------------------------
Key = 2 deleting :
               3               
                       7       
                   6           
                 5             
                4              
--------------------------------------------------------------------
Key = 3 deleting :
       7       
   6           
 5             
4              
--------------------------------------------------------------------
Key = 4 deleting :
   7   
 6     
5      
--------------------------------------------------------------------
Key = 5 deleting :
 7 
6  
--------------------------------------------------------------------
Key = 6 deleting :
7
--------------------------------------------------------------------
Key = 7 deleting :
--------------------------------------------------------------------

REF:

1,http://zh.wikipedia.org/wiki/Treap

2,数据结构与算法分析-C语言描述 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值