伸展树

伸展树及相关操作 伸展树 简要提点 伸展树(Splay Tree)是一种二叉排序树,能在O(log n)内完成插入、查找和删除操作。 伸展树的基本操作都和伸展有关:当带有关键字X的节点被插入时,需要对树进行一系列的伸展旋转使得关键字X的节点成为新的根节点。当查找一个关键字X时,也同样对树进行伸展旋转使得带有关键字X的节点成为根节点。这样下次再查找X时,只需O(1)的时间。 伸展树的数据结构使得访问频繁的关... 阅读详情

        伸展树,是一种二叉排序树。它可以保证从空树开始任意连续M次对树的操作最多花费O(MlogN)时间。虽然这种保证并不排除任意一次操作花费O(N)时间的可能,而且这样的界也也不如每次操作最坏情形的界O(logN)那么短,但是实际效果是一样的:不存在坏的输入序列。一般来说,当M次操作的序列总的最坏情形运行时间为O(MF(N))时,我们说它的摊还(amortized)运行时间为O(F(N))。

        伸展树相比AVL树不需要额外的平衡因子或者高度等信息,在访问符合一定分布的数据集时性能尤佳,而且实现自顶向下的伸展树相对简单。

一,基本的自底向上伸展树

       伸展操作主要是将最近访问的结点通过一系列的旋转置于树的顶端。

 在旋转的时候,可以分为三种情况:

1、zig情况。
    X是查找路径上我们需要旋转的一个非根节点。
    如果X的父节点是根,那么我们用下图所示的方法旋转X到根:


这和一个普通的单旋转相同。
2、zig-zag情况。
在这种情况中,X有一个父节点P和祖父节点G(P的父节点)。X是右子节点,P是左子节点,或者反过来。这个就是双旋转。
先是X绕P左旋转,再接着X绕G右旋转。
如图所示:


3、zig-zig情况。
    这和前一个旋转不同。在这种情况中,X和P都是左子节点或右子节点。
    先是P绕G右旋转,接着X绕P右旋转。
    如图所示:


下面是一个例子,旋转节点c到根上。 


二、基本伸展树操作:
1、插入:
    当一个节点插入时,伸展操作将执行。因此,新插入的节点在根上。
2、查找:
    如果查找成功(找到),那么由于伸展操作,被查找的节点成为树的新根。
如果查找失败(没有),那么在查找遇到NULL之前的那个节点成为新的根。也就是,如果查找的节点在树中,那么,此时根上的节点就是距离这个节点最近的节点。
3、查找最大最小:
        查找之后执行伸展。
4、删除最大最小:
a)删除最小:
    首先执行查找最小的操作。
这时,要删除的节点就在根上。根据二叉查找树的特点,根没有左子节点。
使用根的右子结点作为新的根,删除旧的包含最小值的根。
b)删除最大:
首先执行查找最大的操作。
删除根,并把被删除的根的左子结点作为新的根。
5、删除:
        将要删除的节点移至根。
        删除根,剩下两个子树L(左子树)和R(右子树)。
        使用DeleteMax查找L的最大节点,此时,L的根没有右子树。
        使R成为L的根的右子树。
        如下图示:


三、自顶向下的伸展树:
    在自底向上的伸展树中,我们需要求一个节点的父节点和祖父节点,因此这种伸展树难以实现。因此,我们可以构建自顶向下的伸展树。
    当我们沿着树向下搜索某个节点X的时候,我们将搜索路径上的节点及其子树移走。我们构建两棵临时的树──左树和右树。没有被移走的节点构成的树称作中树。在伸展操作的过程中:
1、当前节点X是中树的根。
2、左树L保存小于X的节点。
3、右树R保存大于X的节点。
开始时候,X是树T的根,左右树L和R都是空的。和前面的自下而上相同,自上而下也分三种情况:
1、zig:


 如上图,在搜索到X的时候,所查找的节点比X小,将Y旋转到中树的树根。旋转之后,X及其右子树被移动到右树上。很显然,右树上的节点都大于所要查找的节点。注意X被放置在右树的最小的位置,也就是X及其子树比原先的右树中所有的节点都要小。这是由于越是在路径前面被移动到右树的节点,其值越大。

2、zig-zig:

在这种情况下,所查找的节点在Z的子树中,也就是,所查找的节点比X和Y都小。所以要将X,Y及其右子树都移动到右树中。首先是Y绕X右旋,然后Z绕Y右旋,最后将Z的右子树(此时Z的右子节点为Y)移动到右树中。注意右树中挂载点的位置。


3、zig-zag:

在这种情况中,首先将Y右旋到根。这和Zig的情况是一样的。然后变成上图右边所示的形状。接着,对Z进行左旋,将Y及其左子树移动到左树上。这样,这种情况就被分成了两个Zig情况。这样,在编程的时候就会简化,但是操作的数目增加(相当于两次Zig情况)。
    最后,在查找到节点后,将三棵树合并。如图:


将中树的左右子树分别连接到左树的右子树和右树的左子树上。将左右树作为X的左右子树。重新最成了一所查找的节点为根的树。

下面是一个查找节点19的例子:


    在例子中,树中并没有节点19,最后,距离节点最近的节点18被旋转到了根作为新的根。节点20也是距离节点19最近的节点,但是节点20没有成为新根,这和节点20在原来树中的位置有关系。

代码:

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

typedef struct SplayTreeNode * SplayTree;
typedef struct SplayTreeNode
{
	int data;
	SplayTreeNode *lchild,*rchild;
} SplayTreeNode;

void BuildSplayTree(SplayTree *T)
{
	int item;
	cin>>item;
	if(item==-1)
	{
		*T = NULL;
	}
	else {
		*T = new SplayTreeNode;
		(*T)->data = item; 
		BuildSplayTree(&((*T)->lchild));
		BuildSplayTree(&((*T)->rchild));
	}
}

SplayTree SingleRotateWithLeft(SplayTree x)
{
	/* x has left child y */
	SplayTree y;
	y = x->lchild;
	x->lchild = y->rchild;
	y->rchild = x;
	return y;
}

SplayTree SingleRotateWithRight(SplayTree x)
{
	/* x has right child y */
	SplayTree y;
	y = x->rchild;
	x->rchild = y->lchild;
	y->lchild = x;
	return y;
}

SplayTree DoubleRotateWithLeft(SplayTree x)
{
	/* x has left child x->lchild  and also 
	x->lchild has a  right child x->lchild->right*/
	x->lchild = SingleRotateWithRight(x->lchild);
	return SingleRotateWithLeft(x);
}

SplayTree DoubleRotateWithRight(SplayTree x)
{
	/* x has right child x->rchild  and also 
	x->rchild has a  left child x->rchild->lchild*/
	x->rchild = SingleRotateWithLeft(x->rchild);
	return SingleRotateWithRight(x);
}

SplayTree Splay(int key,SplayTree X)
{
	/* simple top down  splay, not requiring key in the tree X
	what it does is as described below                      */
	SplayTreeNode N;
	SplayTree left,right;
	
	if (X == NULL)
		return X;
	
	N.lchild = N.rchild = NULL;
	
	left = right = &N;
	
	while (key != X->data) {
		if (key < X->data)
		{
			if (X->lchild == NULL) 
				break;
			if( key < X->lchild->data) {
				/*小于左支路上连续的两个结点*/ 
				X = SingleRotateWithLeft(X);
			}
			/*旋转之后看停止条件是否满足*/
			if (X->lchild == NULL)
					break;
			right->lchild = X;
			right = X;
			X = X->lchild;
		}
		else {
			if ( X->rchild == NULL)
				break;
			if ( key > X->rchild->data) {
				/*大于右支路上连续的两个结点*/ 
				X = SingleRotateWithRight(X);				 
			}
			/*旋转后看是否满足停止条件*/ 
			if (X->rchild == NULL)
					break;
			left->rchild = X;
			left = X;
			X = X->rchild;
		
		}
	}
	left->rchild = X->lchild;
	right->lchild = X->rchild;
	X->lchild = N.rchild;
	X->rchild = N.lchild;
	return X;
} 

bool SplaySearch(int key, SplayTree *T)
{
	SplayTree t = *T;
	while (t != NULL) {
		if (key < t->data)
			t = t->lchild;
		else if (key > t->data)
			t = t->rchild;
		else {
			*T = Splay(key,*T);
			return true;
		}	
	}	
	return false;
} 

SplayTree SplayInsert(int key,SplayTree T)
{
	SplayTree t;
	t = new SplayTreeNode;
	t->data = key;
	t->lchild = t->rchild = NULL; 
	if (T == NULL) {
		T = t;
	}
	else {
		T = Splay(key,T);
		if (key < T->data) {
			t->lchild = T->lchild;
			t->rchild = T;
			T->lchild = NULL;
			T = t;
		}
		else {
			if (T->data <key) {
				t->rchild = T->rchild;
				t->lchild = T;
				T->rchild = NULL;
				T = t;
			}
			else {
				delete t;
			}
		}
	} 
	return T;	
		
}

SplayTree SplayDelete(int key, SplayTree T)
{
	SplayTree t;
	if (T != NULL) {
		
		T = Splay(key, T);
		
		if (key == T->data) {
			if (T->lchild == NULL)
				t = T->rchild;
			else {
				t = T->lchild;
				t = Splay(key,t);
				t->rchild = T->rchild;
			}
			delete T;
			T = t;
		}
	}
	return T;
}

inline int max(int a,int b)
{
	return a>b?a:b;
}
int Height(SplayTree T)
{
	if (T == NULL)
		return 0;
	else
		return 1 + max(Height(T->lchild), Height(T->rchild));
}
void MakeMat(SplayTree T,int root_x,int root_y,int step,int **m)
{
	int lChildPos,rChildPos;
	lChildPos = root_x - step;
	rChildPos = root_x + step;
	if (T == NULL) 
		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 SplayTreeDisplay(SplayTree T)
{
	if(T == NULL)
		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<SplayTree> v;
	queue<SplayTree> q;
	queue<SplayTree> qt;
	q.push(T);
	SplayTree pt;
	while(!q.empty())
	{
		pt = q.front();
		if (pt->lchild != NULL)
			q.push(pt->lchild);
		if(pt->rchild != NULL)
			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;
	}
	
}

int main()
{
	SplayTree T = NULL;
	int i;
	//BuildSplayTree(&T); 
	//SplayTreeDisplay(T);
	int a[] = {4,5,3,1,7,2,6};
 	for(i = 0; i < 6; i++) {
		cout<<"Key = "<<a[i]<<" inserting: "<<endl;
		T = SplayInsert(a[i],T);
		SplayTreeDisplay(T);
		cout<<"--------------------------------------------"
		"--------------------"<<endl;
	}
	
	for(i = 0; i < 6; i++) {
		cout<<"Key = "<<a[i]<<" searching: "<<endl;
		SplaySearch(a[i],&T);
		SplayTreeDisplay(T);
		cout<<"--------------------------------------------"
		"--------------------"<<endl;
	}
	for(i = 0; i < 6; i++) {
		cout<<"Key = "<<a[i]<<" deleting: "<<endl;
		T = SplayDelete(a[i],T);
		SplayTreeDisplay(T);
		cout<<"--------------------------------------------"
		"--------------------"<<endl;
	}
	
	cout<<"Key = "<<19<<" deleting: "<<endl;
	T = SplayDelete(19,T);
	SplayTreeDisplay(T);
	cout<<"--------------------------------------------"
		"--------------------"<<endl;
} 



测试输出:

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


REF:

1,http://www.cnblogs.com/kernel_hcy/archive/2010/03/17/1688360.html

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

3,http://digital.cs.usu.edu/~allan/DS/Notes/Ch22.pdf

Splay Tree(伸展树) 参考:《数据结构(C++语言版)》邓俊辉著 (好书 一、 伸展树(由 D. D. Sleator 和 R. E. Tarjan 于 1985 年发明)也是平衡二叉搜索树的一种形式。相对于 AVL 树,伸展树的实现更为简洁 伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率 伸展树也不需要对基本的二叉 树节点结构做任何附加的要求或改动,更 阅读详情

相关推荐

OpenCode:终端开源AI编程助手,多模型接入与实战指南

AI编程助手正在从IDE侧边栏走向终端环境。其核心原理是让模型直接读取项目文件、执行命令、查看报错,形成从诊断到修复的完整闭环,从而解决传统插件上下文割裂的问题。技术价值在于开源透明、模型无关,既可接入OpenAI等云端服务,也能通过Ollama连接本地模型,兼顾数据安全与离线场景。在工程实践中,它适用于长时间驻留项目、自动修Bug、团队统一AI工具链等需求。OpenCode正是这样一款终端AI助手,支持灵活配置第三方API密钥,提供免费档与Go套餐,并通过Skills技能系统让模型遵循标准操作流程。同时,

weixin_28745821的博客 326

伸展树(Splay)

伸展树(Splay) 伸展树的作用范围很广,在某些情况下甚至可以代替线段树,伸展树最突出的特点就是区间操作:区间翻转,区间插入,区间删除,与其他二叉搜索树相比它能使得总体时间效率得到平摊,使得总效率为O(mlog n),当操作涉及到以区间为单位的位置变动时,就会使用到伸展树

C_eeking的博客 1386

从平衡车到寻迹小车:IMU963RA九轴陀螺仪实战避坑与四元数融合指南

本文详细解析了IMU963RA九轴陀螺仪在机器人姿态控制中的应用,重点探讨了从六轴升级到九轴系统的技术路径及四元数融合算法。通过实战案例,揭示了如何利用地磁计补偿陀螺积分漂移,并提供硬件集成、传感器校准及算法实现的完整解决方案,有效将8小时漂移控制在2度以内。

weixin_27219587的博客 253

Tree | 伸展树

本文目录 一、伸展树的基本概念 二、Splay —— 伸展操作的原理 1、P 是根节点 2、P 不是根节点 Z字型旋转(Zig-zag) 一字型旋转(Zig-zig)—— 左 一字型旋转(Zig-zig)—— 右 三、伸展操作的实现 四、利用伸展树实现其他操作 1、Find(x,S) 2、Insert(x,S) 3、Delete(x,S) 4、Join(S1,S2) ...

weixin_43787043的博客 662

基于Codex Skill的抖音爆款分析与带货视频自动化生成实战

这次我们来看一个基于 Codex 的自动化内容创作项目。核心是利用 Codex 平台的能力,通过自定义的 Skill(技能)来拆解抖音爆款博主的视频模式,并自动生成自己的带货视频。对于内容创作者、电商运营或对短视频自动化感兴趣的技术开发者来说,这是一个将大语言模型(LLM)能力与具体业务场景深度结合的实战案例。 项目的核心价值在于流程自动化。它试图解决一个常见痛点:分析爆款视频的脚本结构、话术、节奏需要大量人工,而模仿创作又耗时费力。通过 Codex 的 Skill 机制,可以将“分析”和“生成”这两个环节

weixin_30420305的博客 383

ESP32连接PDM麦克风操作指南:新手入门必看

手把手教你如何将ESP32与PDM麦克风连接,采集音频数据并用于音频分类应用。内容涵盖硬件接线、代码配置及实际调试技巧,适合初学者快速上手esp32在声音识别场景中的使用。

weixin_42590539的博客 1329

伸展树的查找、插入、删除

在信息处理中,刚被访问的数据,很有可能在短时间内被再次访问。在计算机系统中,同样如此。在总结点数为n的AVL树中,访问m次相邻数据共需要mlogn的时间。如果我们把经常访问的数据都放在树的顶端,那么时间就会减少很多。在此,我们引入了伸展树这一概念。 伸展树的概念 最基本的概念,逐层伸展:节点一旦被访问,就将其转移至树根。这一操作可以经过若干次单旋Zig或Zag操作来完成。自下而上,逐层单旋,直至v...

JTY541464341的博客 1681

wintab开发例程

 タブレットとスタイラスペンを使うと、パソコンに手書きの線を入力できます。筆圧を入力することができるので毛筆のような表現も可能です。ペンの傾きを入力できる機種もあり、アイデア次第で面白いことに使えそうです。  私は昔(94年頃)、WACOMのタブレットを用いたプログラム開発をしたことがあります。当初A3版ほどの大きさのUDというタブレットを使っていて、その後 ArtPad という小さいサイズの

grass168的专栏 3240

伸展树Splay学习笔记

伸展树(英语:Splay Tree)是一种二叉查找树,它能在O(log n)内完成插入、查找和删除操作。它是由丹尼尔·斯立特(Daniel Sleator)和罗伯特·塔扬在1985年发明的。 在伸展树上的一般操作都基于伸展操作:假设想要对一个二叉查找树执行一系列的查找操作,为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法, 在每次查找之后对树进

chutzpah 822

汽车零部件产线实战:C#上位机+YOLO实现螺栓装配到位视觉检测

本项目基于C#上位机+YOLOv8实现汽车零部件产线螺栓装配到位视觉检测,全程贴合产线实际场景,从硬件选型、安装调试,到模型训练、上位机开发,再到项目联调、优化扩展,均提供手把手实操指导,代码可直接复制使用,规避了工业视觉产线检测的高频踩坑点。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1330

学Simulink--基础微电网场景实例:基于Simulink的微电网经济调度优化策略仿真

指标传统调度PSO经济调度(本文)目标值总运行成本(元/h)45.232.5(工况1)降低≥20%调度响应时间(s)25<30储能SOC范围(%)50~50(不变)28~56(动态优化)20~80弃风弃光率(%)0(强制满发)0(优化消纳)0原理:微电网经济调度通过PSO算法优化各单元出力,以总成本最小化为目标,平衡功率平衡与设备约束;建模:Simulink中用实现PSO控制器,结合PV/WT/DG/ESS模型,完成闭环优化;验证。

amy_mhd的博客 67

一个伸展树的实现

伸展树实现(java语言版本) 一、伸展树的基本概念 伸展树是一种二叉搜索树,伸展树也是一种平衡树,不过伸展树并不像AVL树那样对树的平衡有很严格的要求(左右孩子高度之差不能超过1),伸展树通过一系列的伸展操作,可以保证对伸展树的任意连续M次操作,其时间复杂度不会超过MlogN级别,并且伸展树的实现相较于AVL树也简单了很多,不论是插入还是删除算法 二、伸展树的伸展操作 伸展树之所以能够保证MlogN的界,就是因为伸展树的伸展操作,每一次调用伸展树的search方法查找一个结点的时候,如果存在,那么就

西城风雨楼 737

RT-DETR改进策略【模型轻量化】| 替换骨干网络为 GhostNet V3 2024华为的重参数轻量化模型

本文记录的是基于 GhostNetV3 的 RT-DETR轻量化改进方法研究。GhostNetV3的轻量模块采用方法,训练时为深度可分离卷积和1×1卷积添加,推理时通过移除分支、折叠操作,能够在不增加推理成本的同时提高性能,从而实现RT-DETR的轻量化改进。

Limiiiing的博客 971

伸展树(Splay tree)图解与实现

个人技术博客:http://blog.ztgreat.cn 一、伸展树    本文介绍了二叉查找树的一种改进数据结构–伸展树(Splay Tree)。它的主要特点是不会保证树一直是平衡的,但各种操作的平摊时间复杂度是O(log n),因而,从平摊复杂度上看,二叉查找树也是一种平衡二叉树。另外,相比于其他树状数据结构(如红黑树,AVL树等),伸展树的空间要求与编程复杂度要小得多。 伸展树...

小张的专栏 4万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Splay Tree(伸展树)

二叉查找树(BinarySearchTree)能够支持多种动态集合操作。因此,在信息学竞赛中,二叉排序树起着非常重要的作用,它可以被用来表示有序集合、建立索引或优先队列等。 作用于二叉查找树上的基本操作的时间是与树的高度成正比的。对一个含n各节点的完全二叉树,这些操作的最坏情况运行时间为O(logn)。但如果树是含n个节点的线性链,则这些操作的最坏情况运行时间为O(n)。而有些二叉查找树的

2万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

伸展树的特性及实现

除了AVL树,本章将按照二叉搜索树的介绍,继续介绍平衡二叉搜索树家族中的另一个成员—Splay伸展树。 相对于AVL,Splay的实现更为简捷。伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率。伸展树也不需要对基本的二叉树节点结构,做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广。 通常在任意数据结构的生命期内,...

不能说的秘密的博客 7051

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

伸展树c++ 实现

一、为什么要有伸展树 根据

chance_yin 3569

高级搜索树之伸展树

伸展树(Splay Tree)是平衡二叉搜索树的一种形式。相对于 AVL,伸展树的实现更为简捷。伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率。伸展树也不需要对基本的二叉树节点结构,做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广。

_ 3121

伸展树及从上而下的伸展树

我们知道AVL树为了保持严格的平衡,所以在数据插入上会呈现过多的旋转,影响了插入和删除的性能,此时AVL的一个变种 伸展树(Splay)就应运而生了,我们知道万事万物都遵循一个“八二原则“,也就是说80%的人只会用到20%的数据,比如说我们 的“QQ输入法”,平常打的字也就那么多,或许还没有20%呢。   一:伸展树  1:思想     伸展树的原理就是这样的一

Aiphis的博客 660

伸展树你需要了解一下

伸展树(Splay Tree)是一种平衡二叉搜索树,它能在O(log n)内完成插入、查找和删除操作。它是丹尼尔·斯立特Daniel Sleator 和 罗伯特·恩卓·塔扬Robert Endre Tarjan 在1985年发明的。伸展树是一种自调整形式的二叉查找树,它会在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。具体来说,伸展树沿着从某个节点到树根之间的路径,通过一系列的旋转把这个节点搬移到树根去。

技术人集结地 1343

伸展树-搜索树

/ 因为根节点被删除了,搜索会将右子树中节点值最接近查找数值的节点返回,这个节点就是右子树中最小的节点,然后右子树中最小节点必伸展至根,且(因无类同节点)其左子树必空。// 根节点 = 其右子树,也就是原本的根节点已经被删除了。在这种情况中,X有一个父节点P和祖父节点G(P的父节点)。// 令 新的根节点左子树 = 上面存储的左子树。存在,此时有一个隐含信息,因为搜索到了该节点,那么这个节点此时已经被伸展到树根了。关于查询操作中,将节点伸展至根节点的操作,应用伸展(splaying)技术。

lq 1316

伸展树详解

伸展树(Splay Tree)

good good study, day day up! 878

图解双层伸展树

引言 伸展树的出发点是这样的:考虑到局部性原理(刚被访问过的数据,极有可能很快地再次被访问),因此将刚被访问过的节点移(旋转)到根节点。 如果没有了解过AVL树,建议先看下 图解AVL树 伸展策略 那么该如何旋转呢? 逐层伸展 联系刚刚学过的AVL树,我们可以从待访问的节点开始,逐层往上旋转。 我们使用的手段无非是, 当待访问节点v是左孩子,进行一次右旋操作。 若是右孩子,则进行一次左旋操...

日积月累,天道酬勤 1099

伸展树算法c语言,数据结构之伸展树详解

1、 概述二叉查找树(Binary Search Tree,也叫二叉排序树,即Binary Sort Tree)能够支持多种动态集合操作,它可以用来表示有序集合、建立索引等,因而在实际应用中,二叉排序树是一种非常重要的数据结构。从算法复杂度角度考虑,我们知道,作用于二叉查找树上的基本操作(如查找,插入等)的时间复杂度与树的高度成正比。对一个含n个节点的完全二叉树,这些操作的最坏情况运行时间为O(l...

weixin_33274728的博客 562

算法笔记——伸展树

伸展树

m0_67142204的博客 1435
上一篇: 红黑树(RED-BLACK TREE)的插入和删除
下一篇: B-树小结
Scandinavians
博客等级 码龄19年 36粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值