Splay树简介

平衡Splay】学习小记 平衡,顾名思义,平衡的搜索二叉。常见的平衡都能将的深度保持在lg⁡n\lg_nlgn​的级别内,防止退化成链。一些平衡可以通过旋转、分裂、合并等操作完成更加高级的、二叉搜索做不到的操作。 阅读详情

这篇虽不是完全关于linux kernel,但也有些相关。

作者:硅谷农民 http://nongmin.coku.com

计算器算法和数据结构中,有各种多样的树,比如AVL树,红黑树,B+树等等,这几种树主要的主要目的是尽量保持平衡,保证即使在最坏情况下,时间复杂度是O(logN),也就是说,从根节点到最底层的叶子节点,路径不会相差太远。比如B+树,它通过节点的分裂来保持尽量平衡,而且这种树比较散,高度不高,访问路径都比较短,比较适合在数据库中作索引。


但是今天我要说一说splay树,我不知道中文叫什么名字,也许该叫它「变根树」。Splay树与众不同的是:它并不一味追求平衡,而是追求整体的效率。当一个节点被访问以后,通过树的旋转,这个节点被移动到最上层,成为新的根节点。旋转以后,这棵树有可能变得很不平衡。但是,同样一个节点如果再被访问的话,只用一次比较就可以返回了。当这棵树被访问了一段时间以后,常访问的节点就会浮到了上面(靠近根节点),也就是说,splay树天生就有缓存的功能!


Splay
树的主要理论依据(assumption)是应用程序访问树节点的时候,总是有偏颇性的,有些节点访问得多,有些节点访问得少,不停地将访问得多的节点移到顶部,对整个访问效率有好处。理论的证明大家可以参考文献。对有些应用来说,例如网络包处理,这种树能起很大的作用,因为在相近的时间段中,网络包有同样IP的可能性很大。

但是。Splay树的最大缺点是搜索是可能需要写很多次内存,在现代的CPU中,写内存的开销相对而言是挺大的,所以有一种观点是Splay树不适合用在内核编程中。


我欣赏splay树的算法,但我更欣赏它背后说折射出来的思想:尽量追求个体利益最大化,并不能保证总体利益的最大化。二叉树不平衡了,有些节点的访问开销会比平衡的二叉树大,但总体而言,它又提高了效率。一味钻牛角尖,还不如有时候适当的妥协来得更有用一些。计算器算法中,同样的想法也有很多,比如,Linux地输入输出调度器(IO scheduler)设计,一般的想法就是让磁盘越忙,效率越高,但是2.6的内核中,Anticipatory IO Scheduler采取了等一等的策略,反而得到总体的更高效率。


从算法中懂得了一些生活的道理,大概也是搞计算机的一些乐趣吧...


硅谷农民
2006 4/17



参考:

http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf
http://en.wikipedia.org/wiki/Splay_tree
http://www.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl

 

 

更多的资料见:

http://www.fcicq.net/wp/?p=107

http://blog.chinaunix.net/u/9831/showart_109148.html

http://bbs.chinaunix.net/viewthread.php?tid=1122220

【异常】OpenClaw 上下文溢出问题(100% context used 309.9k/200k`)排查与解决 摘要:OpenClaw 运行出现"100% context used 309.9k/200k"报错,表示上下文窗口超出200k Token限制。解决方法包括:1) 重启服务或新建会话清空缓存;2) 修改配置文件提升context_window值;3) 长期优化如限制历史对话轮数、分批处理长文本。该问题通常由输入过长或多轮对话累积导致,需控制单次输入量在阈值内。 阅读详情

相关推荐

别把 ABAP 时间戳当数字算:TIMESTAMP / TIMESTAMPL 的语义、正确用法与项目级避坑指南

ABAP时间戳使用指南与常见陷阱 摘要:ABAP中的时间戳(TIMESTAMP/TIMESTAMPL)本质是UTC时间的数字表示,而非累计秒数。正确用法包括:直接比较时间戳顺序、使用CONVERT TIME STAMP进行时区转换、通过CL_ABAP_TSTMP计算时间差。关键注意事项:绝对不要对时间戳本身进行数学运算,否则会导致非法时间值。实际项目中需特别注意SAP Gateway的ETag处理、跨时区系统集成和CDS视图中的时间戳使用场景,避免将本地时间误存为UTC时间戳或在云迁移时产生时区问题。(14

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 288

平衡详解(Splay

引入 先看例题:(洛谷 P3369 【模板】普通平衡) 您需要写一种数据结构,来维护一些数,其中需要提供以下操作: 1.插入 xxx 数 2.删除 xxx 数(若有多个相同的数,因只删除一个) 3.查询 xxx 数的排名(排名定义为比当前数小的数的个数 +1+1+1 ) 4.查询排名为 xxx 的数 5.求 xxx 的前驱(前驱定义为小于 xxx,且最大的数) 6.求 xxx 的后继(后继定义为大于 xxx,且最小的数) 显然可以使用BST(二叉搜索)完成,它的时间复杂度是 O(logn)O(log

Wu_while的博客 1万+

channel operating margin

intel 大师分享的COM源码,可方便进行通道仿真

数据结构】详细解读 Splay Tree(附完整代码)

本鱼干最近在家忙着玩,大脑许久不怎么用。昨日闲来无事,遂翻看书籍。正巧《机器学习》决策这一块不是太熟悉。本打算品茶而观之,但发现有一名Treap,觉得挺好玩,遂实现了一下,做了几个相关题目(用的STL中的map...因为懒),又深入发现了一种名为Splay,更加好玩,可苦于没有办法用STL里的东西代替它,遂于今日下午深入了解,并写成博客~~水经验~~ 分享之。

qq_25426559的博客 4493

普通平衡 Splay

普通平衡Splay

wanglianda2007的博客 1794

高级搜索——伸展Splay详解

伸展(splay tree),也是平衡二叉搜索的一种形式,但并非严格的平衡。但是其实现相较于AVL和红黑更为简捷。伸展无需时刻都严格地保持全的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率。伸展也不需要对基本的二叉节点结构,做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广。动态版本的我们先不对权值进行扩展,只是先实现一棵基本的Splay,所以节点定义和普通的二叉搜索相同。

EQUINOX1的博客 3687

Splay 简介及代码模板

Splay Tree 是动态链剖分的基础。 ● 左旋和右旋是 Splay Tree 的两个基本操作。它在保证 Splay Tree 的中序遍历序列不变的前提下,调整 Splay Tree 的高度,从而维护 Splay Tree 的平衡。 ● Splay Tree 的核心操作是 rotate(x,k),即将结点 x 旋转到结点 k 的下方。其他所有操作,都是围绕着 rotate(x,k) 进行的。

hnjzsyjyj的专栏 922

SPLAY

前言 根据研究表明,90%的访问都是针对10%的元素。提高这90%的访问的效率,就明显改善了对整个访问的效率。 核心思想:把最近访问过的结点提升到根,后续访问的深度将减小。把这种提升结点的操作称为“伸展Splay”。以伸展操作为基础的二叉排序也就相应称为伸展Splay Tree)。 开始 基于前言中十分有用(坑爹 )的话,于是我们需要用SPLAY来优化时间,即把刚操作的点引到根下,即S...

TL的博客 998

[Splay伸展]splay入门级教程

本弱鸟对于SPLAY的一些理解。。。

SKY的C 1万+

数据结构SPLAY 的 C 代码实现及其算法的摊还分析

本文介绍了Splay(伸展)的基本原理和C语言实现。Splay是一种自适应的二叉搜索,通过splay操作将最近访问的节点移动到根节点,利用访问局部性原理提高频繁访问节点的效率。文章详细阐述了Splay的核心特性,包括自适应性、均摊性能和简单性等,并通过C代码展示了节点结构、基本旋转操作(zig/zag)以及关键的splay操作实现。Splay适用于需要频繁访问最近数据的场景,如输入法词库缓存等应用。

weixin_40901147的博客 1046

c++算法之 - Splay

Splay是一种自平衡二叉搜索,通过"伸展"操作将访问节点移至根节点,在均摊O(logn)时间内完成操作。其核心是旋转和伸展操作,包括三种旋转组合(Zig、Zig-Zig、Zig-Zag)来调整结构。支持插入、查找、删除等基本操作,并能高效处理区间操作(如翻转)。相比AVL和红黑Splay无需存储平衡信息,代码更简洁,特别适合需要频繁调整的动态序列维护场景。通过局部性原理优化性能,使频繁访问的节点靠近根部,适用于文本编辑器、排名查询等应用。

巴巴博一巴巴博一巴巴博一 1021

Splay

Splay Splay是一种BST,允许查找、插入、删除、分割、合并等操作。 Splay的原理: 为了使整个查找时间更少,被查频率高的那些结点应当经常处于靠近根的位置。Splay可以通过旋转的方式把被访问结点旋转到根的位置以减少查找时间。 与Treap的不同: Splay允许把任意结点旋转到根,Treap形态固定所以不能。 Splay分裂、合并更简便。 Splay的操作 提根(把结点x旋转到根) x的父结点是根,只需旋转一次。x是左儿子则右旋,反之左旋,且前后中序顺序不变。 x

GitHub:https://github.com/myp020301 1363

AVL、红黑堆、Splay

对于Splay、AVL、堆、红黑的简单理解【不是很全面】

young_man2的博客 2301

Splay详解

更好的阅读体验 Splay 这是一篇宏伟的巨篇 首先介绍BST,也就是所有平衡的开始,他的China名字是二叉查找. BST性质简介 给定一棵二叉,每一个节点有一个权值,命名为 ** 关键码 **,至于为什么叫这个名字,我也不知道. BST性质也就是,对于中任何一个节点,都满足一下性质. 这个节点的关键码不小于它的左子上,任意一个节点的关键码 这个节点的关键码不大于它的右子上,任意...

weixin_30414155的博客 136

神奇的splay

神奇的splay 总结 splay是一种BST,其通过不断的splay操作维持的平衡;其基本思想是将频率高的点(实际是每次查找的点)通过splay操作旋转到根 核心操作: update(x): 维护信息,类似线段中的push_up rotate(x): 单旋,即将x旋转到其父节点y的位置,需要注意顺序(替换y,x的子加入y, y最为x的子) splay(int x,i...

weixin_38168590的博客 133

Splay

Spaly   众所周知,Splay 是一种平衡二叉查找(不要告诉我你不知道二叉查找是什么qwq 不知道什么是二叉查找的看过来: 关于二叉查找)。在这篇东西的最后我们也解释了为什么我们需要用到平衡二叉查找而不是直接查找,这里就不再赘述了,所以现在直接引入正题吧。 旋转操作   未来解决普通二叉查找被卡成层数过深而时间复杂度升高的问题我们需要引入这样一个旋转操作。这个操作的本质就是在不改变这棵的中序遍历的前提下让这颗的层数减小。具体来说是这样做的(对于左边的那棵:RRR 是 yyy 的祖先

ID246783的博客 4354

Splay模板

3224: Tyvj 1728 普通平衡 感谢博主让我看懂了Splay删除操作写法:https://blog.csdn.net/clove_unique/article/details/50630280 下面为个人用结构体优化了splay的写法,自己以之前写过的一些Splay,加上博客中的理解,自己写了个Splay的模板: #include<algorithm> #in...

creator平 262

算法 {Splay(Inorder中序)}

1

qq_66485519的博客 917
上一篇: The Year 2000 as Seen From the Year 1957
下一篇: 介绍守护进程XINETD与SOCKET程序的含义
sprwig
博客等级 码龄18年 4粉丝 13原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值