伸展树

伸展树及相关操作 伸展树 简要提点 伸展树(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 树,伸展树的实现更为简洁 伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率 伸展树也不需要对基本的二叉 树节点结构做任何附加的要求或改动,更 阅读详情

相关推荐

SCRFD算法解读及环境安装实践

SCRFD检测算法及环境安装

lishanlu136的博客 1009

伸展树(Splay)

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

C_eeking的博客 1386

ESP32—C3实现网页跳转

用户点击HTML页面中的按钮。浏览器根据按钮的href属性向服务器发送HTTP GET请求。服务器根据请求的URL调用相应的回调函数。服务器发送包含新页面HTML内容的HTTP响应。浏览器解析并显示新的HTML页面。这个过程对于用户来说是无缝的,看起来就像是直接从一个页面跳转到另一个页面。实际上,背后发生了HTTP请求和响应的过程。

qq_59527512的博客 1022

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

建立时间与保持时间

建立时间与保持时间的计算 文章目录1、建立时间与保持时间概述及模型2、寄存器之间数据传输时建立时间与保持时间3、寄存器之间数据传输时建立时间余量与保持时间余量计算4、 FPGA允许的最大时钟频率或最小时钟周期5、计算FPGA时钟所允许的最大频率或最小时钟周期6、违反建立和保持时间会发生什么? 1、建立时间与保持时间概述及模型 建立时间(Tsu): 在时钟采样之前,输入必须稳定一段时间,该时间量称为建立时间。 理想最优建立时间: 保持时间(Th): 在时钟沿之后输入到触发器稳定所需的最短时间。 理想最优

Crazzy_M的博客 3万+

Fabric V2.5 通用溯源系统——使用Hyperledger Caliper压力测试

Caliper是一款测试区块链性能的工具,支持Hyperledger Fabric、Ethereum等,支持丰富的测试配置参数,测试完成后将直接输出报告,相较于tape更加专业,但是配置稍微有些复杂。本文将一步一步配置Caliper以测试Fabric V2.5 通用溯源系统中的注册用户、查询用户、农产品上链、农产品查询的区块链性能。

TrueTechLabs 官方博客 1395

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

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

JTY541464341的博客 1681

【纯干货分享】常用高速接口眼图模板合集

文章汇集了常见的高速接口的信号眼图测试模板技术要求,比如,LPDDR5/4、PCIe 5.0/4.0、USB、MIPI等等,方便工程师快速进行查询和使用。

一只豌豆象的博客 3116

伸展树Splay学习笔记

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

chutzpah 822

学Simulink——控制执行场景实例:基于Simulink的智能车辆电子稳定控制(ESC)仿真

本文完成了基于 Simulink 的智能车辆电子稳定控制(ESC),实现了:✅ 构建含轮胎非线性的车辆动力学模型✅ 设计滑模横摆稳定性控制器✅ 实现四轮制动力分配逻辑✅ 验证在双移线低附着场景下的卓越稳定性✅ 为主动安全控制系统开发提供完整范式。

xiaoheshang_123的博客 528

【声纳与人工智能融合——从理论前沿到自主系统实战】第一章 声纳AI的数据基础:仿真、数据集与表征学习

该数据集的特点是包含了多种底质背景(沙地、泥地、碎石区)与噪声条件,适合验证模型的背景抑制能力。Urashima数据集由日本海洋研究开发机构(JAMSTEC)发布,基于自主水下航行器(AUV)采集,包含前视声纳序列数据,主要用于水下导航与避障算法评估,其数据包含了精确的姿态与深度标注,支持三维场景重建算法的训练。北约海洋研究与实验中心(CMRE)发布的CMRE datasets包含侧扫与合成孔径声纳数据,特别适用于跨传感器域自适应研究,数据集中包含了同一区域的多种声纳成像结果,为跨模态学习提供了基准。

u012133341的博客 103

一个伸展树的实现

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

西城风雨楼 737

Python-编写点云处理软件(二)点云软件ui制作之仿CC界面

至本篇结束,我们已经能够获得一个有点模子的界面了,但是具体的功能还没有编写,后续的文章将逐渐完善功能。

weixin_43894929的博客 3953

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

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

小张的专栏 4万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Splay Tree(伸展树)

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

2万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

伸展树的特性及实现

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

不能说的秘密的博客 7051

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

伸展树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、付费专栏及课程。

余额充值