对于给定的数组,如果按照之前的方式进行排序的话,有的时候会得到如下的结果

在其中查找数字 5 ,很幸运只需要两步比较就可以得到最后的结果。但是也有可能变为如下的这种情况

如果这个时候我们是要查找 9 的话就需要一直找到最后,所以这种情况是不好的。为了避免这种效率极端低下的查找过程,可以使用平衡二叉树排序树这种数据结构

1. 相关定义

  平衡二叉排序树要求每个节点的左右子树有着相同高度,或者要求任何节点的左右节点的左右子树高度差不超过1。

  根据定义我们可以判断以下的几棵树是否属于平衡二叉排序树

  上面这个满足定义的要求,是一棵平衡二叉排序树。

  这棵树看起来像是平衡二叉排序树,因为他的深度满足要求;但实际上它并不是,因为首先不是一棵二叉排序树。

  这个也不是平衡二叉排序树,因为它虽然满足了二叉排序树的要求,但是并没有达到平衡的要求。比如说结点 9 的左子树的深度要比右子树的深度大 2,这就超过 1 了。

  这是平衡二叉排序树。

2. 实现原理

  对于一个给定的数组 [3, 2, 1, 4, 5, 6, 7, 10, 9, 8],如果不适用平衡二叉排序树的生成方法,很有可能得到如下的结果

这个结果明显是查找效率极低的,所以使用如下的平衡二叉排序树的方法。前三个数字组成的数组如下图所示

明显这已经是一个不平衡的二叉排序树,我们可以看到左子树的深度减去右子树的深度都是大于零的,所以树向右旋转得到如下图所示的结果

  之后再加上 4 5 两个元素可以得到如下的图像

我们可以看到这个二叉排序树中,对于 2 3 两个结点都是不平衡的,且两者的不平衡因子都是 2 ,在这里是 3 的不平衡导致了 2 不平衡,所以调整 3 4 5 这棵不平衡术就可以了,因为在这两个不平衡点中不平衡因子(BF)都是负数,所以应该将这棵最小不平衡树进行左旋转,如下图所示

  再向其中加入 6 这个结点,如下图所示

在这棵树中可以看到只有根节点 2 是不平衡的,且 BF = -2 < 0,所以需要将根节点 2 向左旋转,得到如下的结果

这个时候可以看到树已经不是一个二叉树,所以需要对 3 进行处理,由于 3 小于 4 ,所以将 3 连接在 4 的左子树的最右端,得到如下图所示的结果

  然后向其中加入数据节点 7 ,得到如下的结果

其中的 5 6 7 构成了最小不平衡树,将它进行左旋转,得到如下结果

  再向其中加入 10 9 两个点,可以发现对于4 6 7 三个结点,它们的 bf = 2 ,所以需要调整二叉排序树,如下图所示

但是这个结点不可以像之前一样通过旋转 7 10 9 这棵子树,因为这个时候, 10 结点的 BF 符号与之前的符号均不相同,所以要首先将 9 10 旋转,之后再将不平衡子树进行旋转,如下图所示

其中左侧是将 9 10 旋转之后得到的结果,而右侧是再经过一层旋转得到二叉平衡树。

  最后向树中添加结点 8,得到的结果如下图所示

明显结点 4 的 BF 为正,结点 6 的 BF 为正,但是结点 9 的 BF 为负,这个时候应该先将 8 7 9 10 进行旋转,使得 BF 值相等,然后再调整二叉排序树,如下图所示

经过第一次旋转之后得到的结果如上图中左图所示,明显 4 6 结点不平衡,所以对 6 结点进行左旋转,得到上图中中间的图,这个时候的树不是二叉树,所以需要对 8 进行处理,因为 8 的值比对应的根节点 7 大,所以将它放在根节点 7 右子树的最左侧,得到上图中右图所示的情况,至此完成了平衡二叉树的生成。

3. 代码

#define LH 1
#define EH 0
#define RH -1typedef struct BiTNode
{int data;int bf;struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;void R_Rotate(BiTree *p)
{BiTree L;L = (*p)->lchild;(*p)->lchild = L->rchild;L->rchild = (*p);*p = L;}void LeftBalance(BiTree *T)
{BiTree L, Lr;L = (*T)->lchild;switch(L->bf){case LH:(*T)->bf = L->bf = EH;R_Rotate(T);break;case RH:Lr = L->rchild;switch(Lr->bf){case LH:(*T)->bf = RH;L->bf = EH;breakcase EH:(*T)->bf = L->bf = EH;break;case RH:(*T)->bf = EH;L->bf = LH;break;}Lr->bf = EH;L_Rotate(&(*T)->lchild);R_Rotate(T);}
}int InsertAVL(BiTree *T, int e, int *taller)
{if( !*T ){*T = (BiTree)malloc(sizeof(BiTNode));(*T)->data = e;(*T)->lchild = (*T)->rchild = NULL;(*T)->bf = EH;*taller = TRUE;}else{if(e == (*T)->data){*taller = FALSE;return FALSE;}if(e < (*T)->data){if(!InsertAVL(&(*T)->lchild, e, taller)){return FALSE;}if(*taller){switch((*T)->bf){case LH:LeftBalance(T);*taller = FALSE;break;case EH:(*T)->bf = LH;*taller = TRUE;break;case RH:(*T)->bf = EH;*taller = FALSE;break;}}}else{if(!InsertAVL(&(*T)->rchild, e, taller)){return FALSE;}if(*taller){switch((*T)->bf){case LH:(*T)->bf = EH;*taller = FALSE;break;case EH:(*T)->bf = RH;*taller = TRUE;break;case RH:RightBalance(T);*taller = FALSE;break;}}}}
}

26. 平衡二叉排序树相关推荐

  1. 【swjtu】数据结构实验8_平衡二叉排序树

    实验内容及要求: 从键盘输入若干两两互不相同的非0整数,直到输入0时停止.将输入的所有非0整数按输入次序插入二叉排序树来构造平衡的二叉排序树.输出平衡的二叉排序树的先序和中序递归遍历次序:按中序递归遍 ...

  2. 大话数据结构:平衡二叉排序树

    基础介绍 平衡二叉排序树为了让二叉树的查找 删除 效率能够达到理论上的最好性能.主要手段就是旋转子树,有左旋和右旋,通过计算节点的平衡值确定如何旋转. 代码 #include "stdio. ...

  3. 二叉排序树和平衡二叉排序树

    二叉排序树又称为二叉查找树,它是一颗特殊的二叉树.(空树) 性质:1.若它的左子树非空,则左子树上的所有结点的值均小于根结点的值. 2.若它的右子树非空,则右子树上的所有结点的值均大于根结点的值. 3 ...

  4. 平衡二叉排序树--调整方法快速记忆方法(渣男丢妻弃子法)

    平衡二叉排序树–调整方法快速记忆方法 首先我们先了解下什么是平衡二叉排序树. 平衡二叉排序树又称AVL树.一棵平衡二叉排序树或者是空树,或者是具有下列性质的二叉排序树: ①左子树与右子树的高度之差的绝 ...

  5. 平衡二叉排序树的创建和实现调整过程

    1.已知一棵二叉树的先序序列为:abcedfgh,中序序列为:bcedaghf,画出该二叉树,并给出其后序序列. 2.已知一组关键字为(15,11,22,5,66,58,36,10,38),按照该元素 ...

  6. 平衡二叉排序树(完整案例详解及完整C代码实现)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  7. python平衡二叉排序树

    话不多说,兄弟萌,show me the code! from chapter8.btSearch import DictBinTree from chapter8.Assoc import Asso ...

  8. 数据结构课设——ASL平衡二叉排序树

    题目 编程实现二叉平衡树的创建.插入.删除和查询 对于给定的这组数二叉平衡树上进行查找,给出两种情况下的查找成功和不成功时的ASL 代码 #include <bits/stdc++.h> ...

  9. 设平衡二叉排序树(AVL树) 的节点个数为n,则其平均检索长度为log2n

    平衡二叉树又称AVL树,它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树, 且左子树和右子树的深度之差的绝对值不超过1,若将二叉树上节点的平衡因子BF定义为该节点的左子树 ...

  10. 二叉排序树、AVL树、红黑树、B树、B+树、Hash树、

    二叉排序树 1.基本应用 二叉排序树也称为也叫二叉查找树,二叉搜索树, BST. 满足二叉查找树的一般性质,是指一棵空树具有如下性质: 对于二叉树中的任何一个非叶子节点,要求左子节点比当前节点值小,右 ...

最新文章

  1. 报名 | 工业大数据分析:机会与挑战讲座
  2. [傅里叶变换及其应用学习笔记] 二十六. 高维傅里叶变换的推导
  3. 开发函数计算的正确姿势——运行 Selenium Java
  4. 程序员Web面试之JSON
  5. 弥勒市召开智慧城市建设规划设计征求意见会
  6. 切换用户_Mac如何在多个用户间快速切换?
  7. 某系统有6台输出设备 有多个进程均需要使用2台_系统设计硬核知识(4)——操作系统的设备管理...
  8. qt 二次开发 研华daq_研华DAQ数据采集卡编程
  9. 怎么做游戏打击感浅述
  10. SolidKit.ERPs ERP集成接口工具(for SOLIDWORKS PDM)
  11. HIMSS宣布 Healthcare IT News和MobiHealth News的国际扩张
  12. element table实现前端分页
  13. cad中如何关掉坐标系显示
  14. 网页原型设计工具设计_网页设计工具从下往下
  15. 用python计算工资工资_python税后工资计算器
  16. XLNet 详解(看不懂你来骂我)
  17. android 中文编码
  18. arm汇编总结---让汇编不再神秘
  19. (免费分享)基于javaweb,ssm旅游景点预定系统
  20. python读取xml文件信息失败_通过XML读取XML文件时出错。

热门文章

  1. 经纬度(度分秒)和十进制相互转换
  2. 大一计算机期末考试操作题word,Word大一计算机考试操作题
  3. SecureCRT绿色破解版(解压即可,无注册机)
  4. Windows 4K低延时H265/H264硬编码直播
  5. 【原创】JS文件替换神器--Chrome ReRes插件
  6. Keil4与keil5共存问题
  7. keil4找不到c语言头文件路径,keil4中头文件路径设置的方法汇总
  8. dbfs和dbm的换算_dB 、dBm、dBuv的概念及换算
  9. html页面点击生成图片并可以下载图片
  10. 国产免费数据库建模工具EZDML3.24发布 支持生成和预览vue文件