伸展树算法c语言,AVL树和伸展树 -数据结构(C语言实现)

读数据结构与算法分析

AVL树

带有平衡条件的二叉树,通常要求每颗树的左右子树深度差<=1

可以将破坏平衡的插入操作分为四种,最后通过旋转恢复平衡

破坏平衡的插入方式

描述

恢复平衡旋转方式

LL

在左儿子的左子树进行插入

右旋转

RR

在右儿子的右子树进行插入

左旋转

LR

在左儿子的右子树进行插入

先左旋转 后右旋转

RL

在右儿子的左子树进行插入

先右旋转 后左旋转

AVL树的实现

AVL树的节点声明

struct AvlNode ;

typedef struct AvlNode *Poisition ;

typedef struct AvlNode *AvlTree ;

AvlTree MakeEmpty(AvlTree T) ;

Position Find(ElementType X, AvlTree T) ;

Position FindMin(AvlTree T) ;

Position FinMax(AvlTree T) ;

AvlTree Insert(ElementType X, AvlTree T) ;

AvlTree Delete(ElementType X, AvlTree T) ;

ElementType Retrieve(Poisition P) ;

struct AvlNode

{

ElementType Element ;

AvlTree Left ;

AvlTree Right ;

int Height ;

}

计算AVL节点高度函数

int Height(Position P)

{

if(P == NULL)

return -1 ;

else

P->Height ;

}

向AVL树插入节点的函数

AvlTree Insert(ElementType X, AvlTree T)

{

if(T == NULL)

{

T = malloc(sizeof(struct AvlTree)) ;

if(T == NULL)

Error("内存不足") ;

T->Element = X ;

T->Height = 0 ;

T-Left = T->Right = NULL ;

}

else if(X < T->Element)

{

T->Left = Insert(X,L->Left,)

if(Height(T->Left) - Height(T->Right)) == 2//如果平衡被破坏了,则执行旋转

if(X < T->Left->Element) //LL

T = SingleRotateWithLeft(T) ;

else //LR

T = DoubleRotateWightLeft(T) ;

}

else if(X > T->Element)

{

T->Right = Insert(X,T->Right) ;

if(Height(T->Right) - Height(T->Left)) == 2//如果平衡被破坏了,则执行旋转

if(X > T->Right->Element) // RR

T = SingleRotateWithRight(T) ;

else //RL

T = DoubleRotateWithRight(T) ;

}

}

在左儿子上的单旋转

右旋

Position SingleRotateLeft(Position K2) //K2为平衡被破坏的点

{

Position K1 ;

K1 = K2->Left ;

K2->Left = K1->Right ;

K1->Right = K2 ;

K2->Height = Max(Height(K2->Left),Height(K2->Right)) + 1;

K1->Height = Max(Height(K1->Left),K2->Height) + ;

return K1 ;

}

在左儿子上的双旋转

先左旋后后旋

Position DoubleRotateRight(Position K2)

{

K3->Left = SinglRotateRight(K3->Left) ;

retrun SinglRotateLeft(K3) ;

}

伸展树

目的:加快访问效率

基本想法:当一个节点被访问后,经过一系列的AVL树的旋转到达根节点

伸展树的实现

类型声明

struct SplayTree ;

typedef struct SplayTree *Position ;

typedef struct SplayTree *SplayTree ;

Position FindMin(SplayTree T) ;

Position FinMax(SplayTree T) ;

Position Find(SpalyTree T, ElementType X) ;

Position Insert(SpalyTree T, ElementType X) ;

Position Delete(SpalyTree T, ElementType X) ;

Position Splay(SpalyTree T, ElementType X) ;

Find函数

Position Find(SplayTree T, ElementType X)

{

if(T == NULL)

return NULL ;

else if(X < T->Left->Element)

return Find(T->Left,X) ;

else if(X > T->Right->Element)

return Find(T-Right,X) ;

return T ;

}

Splay函数

把对应节点旋转至根节点,分在左子树和右子树两种情况 ;

SplayTree Splay(SplayTree T,ElementType X)

{

SplayTree N ,K1,R,L;

N->Left = N->Right = NULL ;

if(T == NULL)

return NULL ;

while(true)

{

if(X < T->Element)

{

if(T->Left == NULL)

break ;

if(X < T->Left->Element)

{

K1 = T->Left ;

T->Left = K1->Right ;

K1->Right = T ;

if(T->Right == NULL)

break ;

}

R->Left = T ;

R = T ;

T = T->Left ;

}

else if(X > Element)

{

if(T->Right == NULL)

return NULL ;

if(X > T-Right->Element)

{

K1 = T->Right;

T->Right = K1->Left;

K1->left = T;

T = K1;

if (T->Right == NULL)

break;

}

L->Right = T ;

L = T ;

T = T->Right ;

}

else

{

break ;

}

}

L->Right = T->Left;

R->Left = T->Right;

T->Left = N->Right;

Tree->Right = N->Left;

return T ;

}

Delete函数

SplayTree Delete(SplayTree T, ElementType X)

{

SplayTree S ;

if(T == NULL)

return NULL ;

if(Find(T,X) == NULL)

return T ;

T = Splay(T, X);

if (T->Left != NULL)

{

S = Splay(T->Left, X);

S->Right = T->Right;

}

else

S = T->Right ;

free(T);

return X;

}

总结

二叉树、AVL树、伸展树都是一种特殊的树,都是为了更好更快的执行某种操作。

二叉查找树,AVL树,伸展树【CH4601普通平衡树】

最近数据结构刚好看到了伸展树,在想这个东西有什么应用,于是顺便学习一下. 二叉查找树(BST),对于树上的任意一个节点,节点的左子树上的关键字都小于这个节点的关键字,节点的右子树上的关键字都大于这个节 ...

伸展树&lpar;一&rpar;之 图文解析 和 C语言的实现

概要 本章介绍伸展树.它和"二叉查找树"和"AVL树"一样,都是特殊的二叉树.在了解了"二叉查找树"和"AVL树"之后, ...

树-伸展树&lpar;Splay Tree&rpar;

伸展树概念 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造. (01) 伸展树属于二 ...

伸展树(Splay Tree)进阶 - 从原理到实现

目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...

poj&lowbar;3580 伸展树

自己伸展树做的第一个题 poj 3580 supermemo. 题目大意 对一个数组进行维护,包含如下几个操作: ADD x, y, d 在 A[x]--A[y] 中的每个数都增加d REVERSE ...

数据结构图解(递归,二分,AVL,红黑树,伸展树,哈希表,字典树,B树,B&plus;树)

递归反转 二分查找 AVL树 AVL简单的理解,如图所示,底部节点为1,不断往上到根节点,数字不断累加. 观察每个节点数字,随意选个节点A,会发现A节点的左子树节点或右子树节点末尾,数到A节点距离之差 ...

数据结构(二) --- 伸展树(Splay Tree)

文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...

数据结构&lpar; Pyhon 语言描述 &rpar; — —第10章:树

树的概览 树是层级式的集合 树中最顶端的节点叫做根 个或多个后继(子节点). 没有子节点的节点叫做叶子节点 拥有子节点的节点叫做内部节点 ,其子节点位于层级1,依次类推.一个空树的层级为 -1 树的术 ...

AVL树、splay树&lpar;伸展树&rpar;和红黑树比较

AVL树.splay树(伸展树)和红黑树比较 一.AVL树: 优点:查找.插入和删除,最坏复杂度均为O(logN).实现操作简单 如过是随机插入或者删除,其理论上可以得到O(logN)的复杂度,但是实 ...

随机推荐

ZooKeeper架构设计及其应用要点

问题导读: 1.ZooKeeper的数据模型是什么 ?2.ZooKeeper应用有哪些陷阱 ?3.每个节点(ZNode)中存储的是什么?4.一个ZNode维护了一个状态结构都包含了什么?5.ZNode ...

tomcat监控脚本

工作所需,匆匆忙忙写了个监控tomcat的shell脚本,大概思路是这样的:先检测tomcat进程是否存在,如果不存在就启动,如果进程存在,检测页面返回码状态,如果是200就是正常,如果不是就重启. ...

【leetcode】Multiply Strings(middle)

Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

判断浏览器是IE的几种方式

【boost】MFC dll中使用boost thread的问题

项目需要,在MFC dll中使用了boost thread(),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...

C&plus;&plus; 出现bug :二位数组的操作运算,求非对角线的元素的和

编写一个通用程序,求出二位数组(行数和列数必须相等)的非对角线的元素之和,试建立类MATRIX完成上述功能 #include using namespace std; ...

javaWEB总结&lpar;10&rpar;&colon;HttpServlet成长史

前言: 从Servlet,ServletConfig到GenericServlet再到Httpservlet的整个过程,相当于Httpservlet的成长史,我们不需要写那么臃肿的代码,开发难度由复杂 ...

AR入门系列-05-Vuforia识别目标视频播放

在识别目标后播放视频我们需要一个插件 Easy Movie Texture 2.36.unitypackage 百度网盘下载地址:http://pan.baidu.com/s/1skT8Xp7 将Ea ...

python中的time模块

time模块--时间获取和转换 time模块提供各种时间相关的功能 与时间相关的模块有:time,datetime,calendar 必要说明: 这个模块的功能不是适用于所有的平台 这个模块中定义的大 ...

hihoCoder1033 交错和 数位DP

题目:交错和 链接:http://hihocoder.com/problemset/problem/1033# 题意:对于一个十进制整数x,令a0.a1.a2.....an是x从高位到低位的数位,定义 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值