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)的复杂度,但是实 ... 
随机推荐
- Grunt中批量无损压缩图片插件--grunt-sprite
			这是什么 这是一个帮助前端开发工程师将css代码中的切片合并成雪碧图的工具,它的主要功能是: 使用二叉树排列算法,对css文件进行处理,收集切片序列,生成雪碧图 在原css代码中为切片添加backgr ... 
- spring boot从redis取缓存发生java.lang.ClassCastException异常
			目录树 异常日志信息 错误原因 解决方法 异常日志信息 2018-09-24 15:26:03.406 ERROR 13704 --- [nio-8888-exec-8] o.a.c.c.C.[.[. ... 
- ffmpeg 简单使用总结
			FFMPEG 生成指定长度的空白音频: ffmpeg -f lavfi -i aevalsrc=0 -t seconds -q:a 9 -acodec libmp3lame out.mp3 FFMPE ... 
- 『ACM C++』 PTA 天梯赛练习集L1 | 038-039
			英剧总导演真的是忙哈哈哈,需要统筹兼顾所有方面,音频组.录音组.演员表演组.道具组.等等一系列的东西,当一个团队的Leader真不容易哈哈. ----------------------------- ... 
- Redis Sentinel 介绍
			Redis Sentinel sentinel的功能: 监控:sentinel节点定期检测redis数据节点,其余sentinel节点是否可达. 通知:sentinel 节点会将故障转移结果通知给 ... 
- windows10上安装mysql
			环境:windwos 10(1511) 64bit.mysql 5.7.14 一.下载mysql 1. 在浏览器里打开mysql的官网http://www.mysql.com/ 2. 进入页面顶部的& ... 
- JsonCpp在vs中使用
			Jsoncpp是c++生成和解析Json数据的跨平台开源库.下面简介如何在vs中使用. 1.官网下载.https://sourceforge.net/projects/jsoncpp/解压文件得到js ... 
- s3c2440系统时钟详解
			一.S3C2440系统时钟体系 S3C2440的时钟控制逻辑可以外接晶振,然后通过内部电路产生时钟源:也可以直接使用内部提供的时钟源,他们通过引脚的设置来选择.时钟逻辑给整个芯片提供了3中时钟:FCL ... 
- 计算机基础和Linux基础
			计算机原理 计算机发展史 机器语言—让机器干活 差分机—让机器的数学运算和逻辑运算只简化成“加法”,计算机只处理“加法” 计算机硬件CPU=运算器+控制器+寄存器(缓存)硬盘=存储器+寄存器寄存器是为 ... 
- [原创]python高可用程序设计方法
			有时候程序上的bug会导致程序引发诸如段错误的情况而导致程序异常退出,这时用crond服务来检测,就会有一段时间程序处于不可用的情况,为了增强程序的可用性,我们可以让子进程处理业务,而让主进程检测子进 ... 
