基础介绍

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

代码

#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status;  /* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* 二叉树的二叉链表结点结构定义 */
typedef  struct BiTNode /* 结点结构 */
{int data;  /* 结点数据 */int bf; /*  结点的平衡因子 */struct BiTNode* lchild, * rchild;   /* 左右孩子指针 */
} BiTNode, * BiTree;/* 对以p为根的二叉排序树作右旋处理, */
/* 处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点 */
void R_Rotate(BiTree* P)
{BiTree L;L = (*P)->lchild;(*P)->lchild = L->rchild;L->rchild = (*P);*P = L;
}/* 对以P为根的二叉排序树作左旋处理, */
/* 处理之后P指向新的树根结点,即旋转处理之前的右子树的根结点0  */
void L_Rotate(BiTree* P)
{BiTree R;R = (*P)->rchild;(*P)->rchild = R->lchild;R->lchild = (*P);*P = R;
}#define LH +1 /*  左高 */
#define EH 0  /*  等高 */
#define RH -1 /*  右高 */ /*  对以指针T所指结点为根的二叉树作左平衡旋转处理 */
/*  本算法结束时,指针T指向新的根结点 */
void LeftBalance(BiTree* T)
{BiTree L, Lr;L = (*T)->lchild; /*  L指向T的左子树根结点 */switch (L->bf){ /*  检查T的左子树的平衡度,并作相应平衡处理 */case LH: /*  新结点插入在T的左孩子的左子树上,要作单右旋处理 */(*T)->bf = L->bf = EH;R_Rotate(T);break;case RH: /*  新结点插入在T的左孩子的右子树上,要作双旋处理 */Lr = L->rchild; /*  Lr指向T的左孩子的右子树根 */switch (Lr->bf){ /*  修改T及其左孩子的平衡因子 */case LH: (*T)->bf = RH;L->bf = EH;break;case EH: (*T)->bf = L->bf = EH;break;case RH: (*T)->bf = EH;L->bf = LH;break;}Lr->bf = EH;L_Rotate(&(*T)->lchild); /*  对T的左子树作左旋平衡处理 */R_Rotate(T); /*  对T作右旋平衡处理 */}
}/*  对以指针T所指结点为根的二叉树作右平衡旋转处理, */
/*  本算法结束时,指针T指向新的根结点 */
void RightBalance(BiTree* T)
{BiTree R, Rl;R = (*T)->rchild; /*  R指向T的右子树根结点 */switch (R->bf){ /*  检查T的右子树的平衡度,并作相应平衡处理 */case RH: /*  新结点插入在T的右孩子的右子树上,要作单左旋处理 */(*T)->bf = R->bf = EH;L_Rotate(T);break;case LH: /*  新结点插入在T的右孩子的左子树上,要作双旋处理 */Rl = R->lchild; /*  Rl指向T的右孩子的左子树根 */switch (Rl->bf){ /*  修改T及其右孩子的平衡因子 */case RH: (*T)->bf = LH;R->bf = EH;break;case EH: (*T)->bf = R->bf = EH;break;case LH: (*T)->bf = EH;R->bf = RH;break;}Rl->bf = EH;R_Rotate(&(*T)->rchild); /*  对T的右子树作右旋平衡处理 */L_Rotate(T); /*  对T作左旋平衡处理 */}
}/*  若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个 */
/*  数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树 */
/*  失去平衡,则作平衡旋转处理,布尔变量taller反映T长高与否。 */
Status InsertAVL(BiTree* T, int e, Status* taller)
{if (!*T){ /*  插入新结点,树“长高”,置taller为TRUE */*T = (BiTree)malloc(sizeof(BiTNode));(*T)->data = e; (*T)->lchild = (*T)->rchild = NULL; (*T)->bf = EH;*taller = TRUE;}else{if (e == (*T)->data){ /*  树中已存在和e有相同关键字的结点则不再插入 */*taller = FALSE; return FALSE;}if (e < (*T)->data){ /*  应继续在T的左子树中进行搜索 */if (!InsertAVL(&(*T)->lchild, e, taller)) /*  未插入 */return FALSE;if (*taller) /*   已插入到T的左子树中且左子树“长高” */switch ((*T)->bf) /*  检查T的平衡度 */{case LH: /*  原本左子树比右子树高,需要作左平衡处理 */LeftBalance(T);   *taller = FALSE; break;case EH: /*  原本左、右子树等高,现因左子树增高而使树增高 */(*T)->bf = LH; *taller = TRUE; break;case RH: /*  原本右子树比左子树高,现左、右子树等高 */(*T)->bf = EH; *taller = FALSE; break;}}else{ /*  应继续在T的右子树中进行搜索 */if (!InsertAVL(&(*T)->rchild, e, taller)) /*  未插入 */return FALSE;if (*taller) /*  已插入到T的右子树且右子树“长高” */switch ((*T)->bf) /*  检查T的平衡度 */{case LH: /*  原本左子树比右子树高,现左、右子树等高 */(*T)->bf = EH; *taller = FALSE;    break;case EH: /*  原本左、右子树等高,现因右子树增高而使树增高  */(*T)->bf = RH; *taller = TRUE; break;case RH: /*  原本右子树比左子树高,需要作右平衡处理 */RightBalance(T); *taller = FALSE; break;}}}return TRUE;
}int main(void)
{int i;int a[10] = { 3,2,1,4,5,6,7,10,9,8 };BiTree T = NULL;Status taller;for (i = 0; i < 10; i++){InsertAVL(&T, a[i], &taller);}printf("本样例建议断点跟踪查看平衡二叉树结构");return 0;
}

大话数据结构:平衡二叉排序树相关推荐

  1. 大话数据结构 : 二叉排序树

    二叉排序树 二叉排序树的好处在于插入 删除 查找的效率很高,比线性表和数组都好 二叉树稍微难一点的敌方在于删除,在删除一个既有左子树也有右子树的节点时比较麻烦,策略就是将要删除的节点的左子树中向右查找 ...

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

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

  3. 《大话数据结构》读书笔记-查找

    写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 8.1 开场白 8.2 查找概论 8. ...

  4. 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 21

    大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 211 第 ...

  5. 《大话数据结构》1、2数据结构、算法

    大话数据结构 大话设计模式 head first设计模式 Java核心技术 卷1 深入理解Java虚拟机(JVM高级特性与最佳实践) 图解HTTP 大话数据结构 数据结构介绍, 算法推导大O阶的方法, ...

  6. 《大话数据结构》简体中文版勘误

    尽管已经很仔细的检查和审核,但错误还是没有能避免.以下的错误,有些是作者的笔误或者表述不清,有些是编辑审稿时不理解造成的错误,有些是美编改图时的错误,有些是印刷厂印刷时的错误.虽然出错的原因很多,但总 ...

  7. 《大话数据结构》读书笔记-树

    写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 6.2 树的定义 6.2.1 结点分类 ...

  8. 《大话数据结构》笔记——第8章 查找(二)

    文章目录 8.6 二叉排序树 8.6.1 二叉排序树查找操作 8.6.2 二叉排序树插入操作 8.6.3 二叉排序树删除操作 8.6.4 二叉排序树总结 8.7 平衡二叉树( AVL树 ) 8.7.1 ...

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

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

最新文章

  1. nodejs -- promise的返回
  2. python 替换array中的值_Python五个隐藏的特性,你可能从未听说过
  3. KubeVela + KEDA:为应用带来“与生俱来”的弹性伸缩能力
  4. 第二阶段_第一小节_小知识
  5. php之变量覆盖漏洞讲解
  6. 文字输入限制_从拼音输入法的兴起看汉字文化圈的衰落
  7. 源码安装MySQL5.5.20
  8. Vijos1755 靶形数独 Sudoku NOIP2009 提高组 T4 舞蹈链 DLX
  9. SAP物料编码- -
  10. 3D数学基础:向量运算
  11. 17分钟过桥,过桥最短时间问题
  12. 判断IP是否在IP段内
  13. Micropython加速物联网开发8 - 2G网络TCP通信
  14. Bootloader和Linux启动过程总结
  15. iapp教程从入门到精通全部,iapp怎么做软件教程
  16. 2019浙江ACM省赛部分题解-ABDEFGHIJK
  17. RSA生成公私钥并加解密
  18. Android wifi PNO扫描流程(Andriod O)
  19. Ubuntu下有线连接开无线WIFI的3种方式
  20. Nexus的安装和应用

热门文章

  1. JAVA的网络编程【转】
  2. sharepoint 2010 使用WinForm获取 SPSite对象
  3. Wireshark数据分析IP
  4. Mysql 日期、字符串、时间戳互转
  5. Vue2.0 传值方式
  6. 微信小程序使用template模板
  7. 记录一个layui框架之自定义模块出现的问题
  8. error: undefined reference to 'cv::_OutputArray::_OutputArray(std::__ndk1
  9. Vs工程高版本向低版本迁移
  10. SLAM: 图像角点检测的Fast算法(时间阈值实验)