- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
平衡二叉数
{treap示范代码:
标准的代码缩进风格,优美的算法实现。
经典标程,完全掌握后水平会提高很多
不改变bst的性质(在bst所有子树中均满足:左子树的所有节点=根=右子树的所有节点)
通过旋转操作,使根的hr最小(即所有的hr构成堆的关系)
}
var
//l[i],r[i],v[i]:i号结点的左儿子、右儿子,关键值
//hr[i]:i号节点的优先值(treap所有子树中,根的hr必须是最小的)
//s[i]:i号节点为根的子树节点总数
l,r,hr,s,v:array[0..2000000]of longint;
n,root,m:longint;
procedure init;//初始化
begin
readln(n);
m:=0;
//randomize; //考试要求程序每次运行结果必须一致,慎用。确实要用:randomize 100;
fillchar(s,sizeof(s),0);
fillchar(l,sizeof(l),0);
fillchar(r,sizeof(r),0);
root:=0;
end;
//旋转是平衡二叉树的精髓,它不会改变bst的性质(左子树=根=右子树)
//左旋使树的左子树深度+1,右子树深度-1
//右旋使树的右子树深度+1,左子树深度-1
procedure l_rotate(var x:longint);inline;//左旋以x为根的子树(注意var参数及意义)
var
y:longint;
begin
y:=r[x]; //保存x的右儿子到y中
r[x]:=l[y]; //将y的左儿子作为x的右儿子
l[y]:=x; //x作为y的左儿子
s[y]:=s[x]; //维护旋转后的子树大小
s[x]:=s[l[x]]+s[r[x]]+1;
x:=y; //y为根
end;
procedure r_rotate(var x:longint);inline;//右旋以x为根的子树
var
y:longint;
begin
y:=l[x];
l[x]:=r[y];
r[y]:=x;
s[y]:=s[x];
s[x]:=s[l[x]]+s[r[x]]+1;
x:=y;
end;
//插入(递归,if key=root,则插入到左子树,否则到右子树,直到尽头再新建节点)
procedure insert(var k,key:longint);inline;
begin
if k=0 then//已到尽头,新建节点并写入key及随机值hr
begin
inc(m);
v[m]:=key;
s[m]:=1;
hr[m]:=random(maxlongint);
k:=m;//修改k,使父节点指向当前节点(修改前从父节点指向0)
exit;
end;
inc(s[k]);
if key=v[k] then//若key=根则插入到左子树,否则到右子树
begin
insert(l[k],key);//若l[k]=0,到下层则新建节点并修改l[k]=m
if hr[l[k]]hr[k] then //旋转
r_rotate(k);
exit;
end;
if keyv[k] then
begin
insert(r[k],key);
if hr[r[k]]hr[k] then
l_rotate(k);
exit;
end;
end;
(删除:在k号节点为根的子树中删除key
基本方法:由于是静态结构,为了提高效率,并没真正删除
若找到则删除,若没找到,则删除查找尽头的节点
主程序中需判断返回值,若不等于key,重新插入key即可
找到后的处理:
若为叶节点,直接删除,否则,将要删除的节点左子树的最右节点(思考:为什么?)代替它
)
function delete(var k:longint;key:longint):longint;inline;
begin
dec(s[k]);//维护节点总数
//如果找到,或已到尽头
if (key=v[k])or(l[k]=0)and(key=v[k])or(r[k]=0)and(keyv[k]) then
begin
delete:=v[k];//返回要删除的节点(不一定=key)
if (l[k]=0)or(r[k]=0) then //
原创力文档


文档评论(0)