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树和伸展树 -数据结构(C语言实现)的更多相关文章
- 二叉查找树,AVL树,伸展树【CH4601普通平衡树】
最近数据结构刚好看到了伸展树,在想这个东西有什么应用,于是顺便学习一下. 二叉查找树(BST),对于树上的任意一个节点,节点的左子树上的关键字都小于这个节点的关键字,节点的右子树上的关键字都大于这个节 ...
- 伸展树(一)之 图文解析 和 C语言的实现
概要 本章介绍伸展树.它和"二叉查找树"和"AVL树"一样,都是特殊的二叉树.在了解了"二叉查找树"和"AVL树"之后, ...
- 树-伸展树(Splay Tree)
伸展树概念 伸展树(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_3580 伸展树
自己伸展树做的第一个题 poj 3580 supermemo. 题目大意 对一个数组进行维护,包含如下几个操作: ADD x, y, d 在 A[x]--A[y] 中的每个数都增加d REVERSE ...
- 数据结构图解(递归,二分,AVL,红黑树,伸展树,哈希表,字典树,B树,B+树)
递归反转 二分查找 AVL树 AVL简单的理解,如图所示,底部节点为1,不断往上到根节点,数字不断累加. 观察每个节点数字,随意选个节点A,会发现A节点的左子树节点或右子树节点末尾,数到A节点距离之差 ...
- 数据结构(二) --- 伸展树(Splay Tree)
文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...
- 数据结构( Pyhon 语言描述 ) — —第10章:树
树的概览 树是层级式的集合 树中最顶端的节点叫做根 个或多个后继(子节点). 没有子节点的节点叫做叶子节点 拥有子节点的节点叫做内部节点 ,其子节点位于层级1,依次类推.一个空树的层级为 -1 树的术 ...
- AVL树、splay树(伸展树)和红黑树比较
AVL树.splay树(伸展树)和红黑树比较 一.AVL树: 优点:查找.插入和删除,最坏复杂度均为O(logN).实现操作简单 如过是随机插入或者删除,其理论上可以得到O(logN)的复杂度,但是实 ...
随机推荐
- Windows中杀死某个端口对应的进程
netstat -ano | findstr 3000 //列出进程极其占用的端口,且包含 3000 tasklist | findstr 17692 // 查看是什么程序占用的 taskkill - ...
- 【oracle笔记2】约束
约束 *约束是添加在列上的,用来约束列的. 1. 主键约束(唯一标识) ***非空*** ***唯一*** ***被引用***(外键时引用主键) *当表的某一列被指定为主键后,该列就不能为空,不能有重 ...
- 并发、并行与C++多线程——基础一
1.什么是并发? 并发指的是两个或多个独立的活动在同一时段内发生.生活中并发的例子并不少,例如在跑步的时候你可能同时在听音乐:在看电脑显示器的同时你的手指在敲击键盘.这时我们称我们大脑并发地处理这些事 ...
- Python基础知识--Slice(切片)和Comprehensions(生成式)
最近在Youtube的Python视频教程上学习Python相关的基础知识,视频由Corey Schafer制作,讲得十分简单明了,英文发音也比较清晰,几乎都能听懂,是一个不错的Python入门学习的 ...
- Nginx(haproxy)+keepalived+Tomcat双主高可用负载均衡
周末的时候一个正在学Linux的朋友问我,高可用怎么玩?我和他微信了将近三个小时,把Nginx和haproxy双主高可用教给他了,今天突然想把这个给写进博客里,供给那些正在学习Linux系统的朋友们, ...
- PHP文档生成器(PHPDoc)的基本用法
目录 PHP文档生成器(PHPDoc)的基本用法 PHPDoc概述 安装 PHPDoc注释规范 页面级别的注释 代码级别的注释 生成API文档 额外软件 PHP文档生成器(PHPDoc)的基本用法 P ...
- oracle 用户尝试登录失败锁定策略及修改
-- 修改密码的有效期策略, 永不过期SQL> ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;Profile altered ...
- 【C】关键字void的用法
void有两种功能 [1]没有 [2]任意类型 void出现的位置不同会有不同的解释 [1]void func( void ) func左边的void,代表『没有返回值』 func右边的括弧里的voi ...
- IAP笔记
1) 首先是IAP BootLoader程序设置:根据common.h里面的宏定义,设置BootLoader所占用的Flash空间. 2) 设置IAP UserApp程序设置:该型号Flash ...
- 分享一个强大的makedown编辑器
Yosoro 官网地址 https://yosoro.coolecho.net/ 很强大,支持直接粘贴图片,是直接上传到github仓库. 可直接导出md,html,pdf格式,特别方便 找了好几天的 ...