首页 > 其他分享 >平衡二叉查找树--splay

平衡二叉查找树--splay

时间:2023-08-07 19:45:26浏览次数:36  
标签:左子 -- 二叉 splay fa 查找 旋转 节点

  splay树,又称伸展树,是一种平衡二叉查找树,通过不断把每个节点旋转到根节点能够在O(logN)的时间内完成插入、查找以及删除的操作,并且能保持平衡不会退化成链

一、关于二叉查找树

  首先,二叉查找树肯定是个二叉树(废话),每个节点的左子节点的值小于该节点的值小于右子节点的值。这个定义听起来十分耳熟 ,是的,堆就是一种二叉查找树

这是卡比,卡比堆

 

  一般二叉查找树的每个节点会带两种变量,一种是优先级,一种是该节点所代表的信息,以该节点的优先级建堆就可以得到一个二叉查找树

  很显然二叉查找树找到一个节点所花费的时间与其深度成正比,最好情况下花费为O(log n),最坏情况下为O(n),即,树退化成了一条链

  当花费为O(log n)时,树是一种类似完全二叉树的形态,这个时候我们称这棵树是平衡的,即这棵树是一个平衡查找二叉树(是的,这个名字就是如此的简单粗暴)

二、平衡树

   如果一棵树的每一个节点的左子树和右子树的高度差最多为一,则称这个树是平衡的,一个合理的二叉搜索树即一个平衡查找二叉树的插入和查找时间可以缩短到O(log n)(这是显然的,因为当这棵树是平衡的时其深度会最小)

  在插入和删除的过程中,二叉查找树可能会失衡,平衡树会通过“旋转”操作调整整棵二叉树的形态,其基本操作为左旋(zig)右旋(zag),若要被旋转的点是其父节点的左子节点则进行右旋,反之左旋

   为了使得这棵树的中序遍历不变,左旋内容如下:

  一、使该节点的左子树成为该节点父节点的右子树

  二、使该节点的父节点成为该节点的左子树

   右旋同理

  经过尝试,如果某个节点需要连续进行若干次(大于等于4次)的左旋或若干次右旋操作时,会有一种更优的旋转方法称为双旋

  就比如下面这个例子,若我要把节点5旋转到根节点

  最终这棵树的深度是5

  但如果每次旋转节点5之前我们先旋转其父节点,然后再旋转节点5,直到节点5成为根节点,最终会有不同的效果

     显然,第二种转法在转完后整棵树的深度比第一种转法整棵树的深度小一,根据前文提到的关于查找树的复杂度,第二种转法更优

  这还只是五次右旋,如果连续旋转的次数更多,第二种转法与第一种的差距会越来越大,第二种转法就是所谓的双旋

  看下代码

void rotate(int x)
{
	int fa=f[x],grand=f[fa],son1=get(x),son2=(son1+1)%2;//f存储某节点的父节点编号 get是查找该节点是其父节点的左子节点还是右子节点 0为左 1为右 
	sons[fa][son1]=sons[x][son2];//将子节点挂到父节点上去 
	f[sons[fa][son1]]=fa;
	sons[x][son2]=fa;
	f[fa]=x;//更新关系 
	f[x]=grand;
	if(grand)
	{
		sons[grand][sons[grand][1]==fa]=x;//如果有祖父节点要令祖父节点成为该节点的父节点 
	}
	//upd(fa);
	//upd(x);
}
void splay(int x)
{
	for(int fa;fa=f[x];rotate(x))//旋转直到x成为根节点 
	{
		if(f[fa]) rotate((get(x)==get(fa))?fa:x);//双旋 
	}
	root=x;//更新根节点 
}

  

标签:左子,--,二叉,splay,fa,查找,旋转,节点
From: https://www.cnblogs.com/qj-Network-Box/p/17610148.html

相关文章

  • 目录穿越
    目录穿越概念目录穿越(DirectoryTraversal)攻击是黑客能够在Web应用程序所在的根目录以外的文件夹上,任意地存取被限制的文件夹、执行命令或查找数据。目录穿越攻击,也有人称为PathTraversal攻击。目录穿越的漏洞危害攻击者可以使用目录穿越攻击来查找、执行或存取Web应用程序......
  • 暑假周记(8.7)
    昨天晕车吐得导致今天都难受,直接跟老妈请假不上课了,歇了一天。staticStringcopyValueOf(char[]data):返回指定数组中表示该字符序列的StringstaticStringcopyValueOf(char[]data,intoffset,intcount):返回指定数组中表示该字符序列的StringbooleanendsWith(Stringsuffi......
  • 搭建k8s集群错误
    1etcd8月1014:12:32k8master-1etcd[23435]:{"level":"warn","ts":"2022-08-10T14:12:32.069+0800","caller":"rafthttp/http.go:500","msg":"requestclusterIDmismatch","loc......
  • 行业追踪,2023-08-07
    自动复盘2023-08-07凡所有相,皆是虚妄。若见诸相非相,即见如来。k线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让市场来告诉你跟踪板块总结:成交额超过100亿排名靠前,macd柱由绿转红成交量要大于均线有必要给每个行......
  • 【Java】从头开始的Java复健day2
    用的书:《Java从入门到精通》day1(3.1-3.3):【Java】从头开始的Java复健day1第三章Java语言基础3.4运算符赋值运算符=如果一个表达式中有两个以上的“=”,会从最右方的“=”开始处理算术运算符加法+减法-乘法*除法/(0不能当除数)取余%自增自减++a:先+1再使用a--a......
  • ciscn_2019_c_1
    ciscn_2019_c_10x01简单的ret2libc3filechecksec——64-bit开NX0x02运行一下看看再看看IDA研究了半天发现是让你加解密的再看看stringwindow没用system和binsh又发现加密函数里有gets函数,可构成栈溢出0x03分析大致流程就是利用一个程序已经执行过的函数去泄......
  • ip变化规律
    我电脑连的网络ip地址变了,查了下原因:原文链接:https://baijiahao.baidu.com/s?id=1756975714460090406&wfr=spider&for=pc 一、1、局域网内可以设置固定的IP地址,也可以随机得到不同的IP地址,可以人为控制。 2、在互联网一般都是电信商随机分配一个IP,每次拨号的IP地址都是不......
  • go基础-函数
    概述在任何语言中函数都是极其重要的内容,业务功能都是由一个或多个函数组合完成。go语言是函数式编程语言,函数是一等公民,可以被传递、有函数类型,go语言有三种类型的函数,普通函数、匿名函数(Lambda函数)、方法函数。go语言函数有独特属性,可以有多个返回值,需要使用多个变量接收、函......
  • 可观测性平台夜莺开源项目发布V6正式版!
    夜莺开源项目在2023.7月底发布了V6版本,这个版本开始,项目目标不止于做一款开源监控系统,而是要做一款开源可观测性平台,不过路漫漫其修远兮,初期只是把日志数据源引入并完成了基本的可视化,后续会着力打通指标和日志的数据串联以及数据特征提取。欢迎小伙伴一起参与共建。夜莺V6版本......
  • axios 请求拦截(request)与响应拦截(response)
    1.请求拦截(request)请求拦截就是在发ajax之前做些什么!例如:可以在请求拦截里面加个token请求头,做些判断等等!语法:axios.interceptors.request.use((config)=>{},(error)=>{})1.1.参数1:(config)=>{}请求正确走的函数1.2.参数2:(error)=>{}请求错误走的函数1.3.代码案......