11
30
2015
0

我的第一棵treap~

treap构造比线段树要容易得多~主要核心就是【通过旋转让BST的Pro域满足堆的性质】

所以线段树笔记还没写完呢..发条文章只是证明自己还在努力往前走;<

#include<iostream>
#include<cstring>
#include<algorithm>
#include<ctime>
//#include<Ryan.Treap>
//这里的heap为小根堆(这里的小并不严格)
//0表示无该节点,叶节点的左右结点均为0
using namespace std;
const int M=10000+5;
struct Treap
{
	int key;//值
	int pro;//优先级
	int L,r;//左右结点编号
	int Ln,rn;//左右子树节点个数
}Tree[M];
void Zig(int &p)
//左旋:当前根节点变为其右节点的左子节点,其右节点变为根节点
{
	int t=Tree[p].r;//p的右节点叫r
	//关键变化:t将他的左节点给p作为右节点
	//t的左节点由p补上
	//这两个步骤显然是不能颠倒的
	Tree[p].r=Tree[t].L;
	Tree[t].L=p;
	//显而易见的变化:
	//因为t把它的左子树给p当做右子树
	Tree[p].rn=Tree[t].Ln;
	Tree[t].Ln=1+Tree[p].Ln+Tree[p].rn;
	p=t;//苍天已死,黄天当立——根节点改变
}
void Zag(int &p)
//右旋:当前根节点变为其左节点的右子节点,其左节点变为根节点
{
	int t=Tree[p].L;
	Tree[p].L=Tree[t].r;
	Tree[t].r=p;
	Tree[p].Ln=Tree[t].rn;
	Tree[t].rn1+Tree[p].Ln+Tree[p].rn;
	p=t;
}
void Insert(int &p,int x)//父节点编号
{
	if(p==0)//该节点没有父节点
	{
		tot++;p=tot;
		Tree[p].key=x;
		Tree[p].L=Tree[p].r=0;
		Tree[p].Ln=Tree[p].rn=0;
		Tree[p].pro=rand%10000;
		return;//递归的出口
	}
	if(x<=Tree[p].key)
	//递归插入左子树到叶节点,然后逐层往上依据优先级旋转调整位置
	{
		Insert(Tree[p].L,x);
		Tree[p].Ln++;
		if(Tree[Tree[p].L].pro<Tree[p].pro) Zag(p);
	}
	else
	{
		Insert(Tree[p].r,x);
		Tree[p].rn++;
		if(Tree[Tree[p].r].pro<Tree[p].pro) Zig(p);
	}
}
void Del(int &p,int x)//在编号为p的子树中删除数值x
{
	if(x<Tree[p].key)
	{
		Tree[p].Ln--;//先改变p的属性
		Del(Tree[p].L,x);//再从左子树中递归删除
	}
	else if(x>Tree[p].key)
	{
		Tree[p].rn--;
		Del(Tree[p].r,x);
	}
	else if(x==Tree[p].key)//找到要删除数值对应的节点
	{
		if(!Tree[p].L&&!Tree[p].r)
		//递归出口!
		{
			p=0;
			Tree[p].key=0;
//		Tree[p].pro=0;
			return;
		}
		int lp=INF,rp=INF;//inf应用于一端子树不存在的情况
		if(Tree[p].L) lp=Tree[Tree[p].L].pro;
		if(Tree[p].r) rp=Tree[Tree[p].r].pro;
//有点像物理过程?权值重吊在下面,权值轻的被拉上去
		if(lp<=rp)
		{
			Zag();
			Tree[p].rn--;//这个好好理解!
			Del(Tree[p].r,x);
		}
		else
		{
			Zig();
			Tree[p].Ln--;
			Del(Tree[p].L,x);
		}
	}
}
bool Find(int p,int x)
{
	if(p==0) return 0;
	else if(x==Tree[p].key) return 1;
	else if(x<Tree[p].key) return Find(Tree[p].L,x);
									else return Find(Tree[p].r,x);
}
int Findk(int p,int k)//不可以加&
{
	if(1+Tree[p].Ln+Tree[p].rn<k) return -1;
	if(1+Tree[p].Ln==k) return Tree[p].key;
	if(k<Tree[p].Ln) return Findk(Tree[p].L,k);
	else return Findk(Tree[p].r,k-1-Tree[p].Ln);
}
/*生成随机数*/
#include<iostream>
int main()
{
	int x;
	srand((unsigned)time(NULL));//初始化随机函数
	for(int i=1;i<=10;i++)
	{
		x=rand()%100;
		cout<<x<<endl;
	}
	return 0; 
}
Category: 平衡树 | Tags: | Read Count: 235

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com