大话数据结构:平衡二叉排序树
基础介绍
平衡二叉排序树为了让二叉树的查找 删除 效率能够达到理论上的最好性能。主要手段就是旋转子树,有左旋和右旋,通过计算节点的平衡值确定如何旋转。
代码
#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;
}
大话数据结构:平衡二叉排序树相关推荐
- 大话数据结构 : 二叉排序树
二叉排序树 二叉排序树的好处在于插入 删除 查找的效率很高,比线性表和数组都好 二叉树稍微难一点的敌方在于删除,在删除一个既有左子树也有右子树的节点时比较麻烦,策略就是将要删除的节点的左子树中向右查找 ...
- 【swjtu】数据结构实验8_平衡二叉排序树
实验内容及要求: 从键盘输入若干两两互不相同的非0整数,直到输入0时停止.将输入的所有非0整数按输入次序插入二叉排序树来构造平衡的二叉排序树.输出平衡的二叉排序树的先序和中序递归遍历次序:按中序递归遍 ...
- 《大话数据结构》读书笔记-查找
写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 8.1 开场白 8.2 查找概论 8. ...
- 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第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 第 ...
- 《大话数据结构》1、2数据结构、算法
大话数据结构 大话设计模式 head first设计模式 Java核心技术 卷1 深入理解Java虚拟机(JVM高级特性与最佳实践) 图解HTTP 大话数据结构 数据结构介绍, 算法推导大O阶的方法, ...
- 《大话数据结构》简体中文版勘误
尽管已经很仔细的检查和审核,但错误还是没有能避免.以下的错误,有些是作者的笔误或者表述不清,有些是编辑审稿时不理解造成的错误,有些是美编改图时的错误,有些是印刷厂印刷时的错误.虽然出错的原因很多,但总 ...
- 《大话数据结构》读书笔记-树
写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 6.2 树的定义 6.2.1 结点分类 ...
- 《大话数据结构》笔记——第8章 查找(二)
文章目录 8.6 二叉排序树 8.6.1 二叉排序树查找操作 8.6.2 二叉排序树插入操作 8.6.3 二叉排序树删除操作 8.6.4 二叉排序树总结 8.7 平衡二叉树( AVL树 ) 8.7.1 ...
- 平衡二叉排序树--调整方法快速记忆方法(渣男丢妻弃子法)
平衡二叉排序树–调整方法快速记忆方法 首先我们先了解下什么是平衡二叉排序树. 平衡二叉排序树又称AVL树.一棵平衡二叉排序树或者是空树,或者是具有下列性质的二叉排序树: ①左子树与右子树的高度之差的绝 ...
最新文章
- nodejs -- promise的返回
- python 替换array中的值_Python五个隐藏的特性,你可能从未听说过
- KubeVela + KEDA:为应用带来“与生俱来”的弹性伸缩能力
- 第二阶段_第一小节_小知识
- php之变量覆盖漏洞讲解
- 文字输入限制_从拼音输入法的兴起看汉字文化圈的衰落
- 源码安装MySQL5.5.20
- Vijos1755 靶形数独 Sudoku NOIP2009 提高组 T4 舞蹈链 DLX
- SAP物料编码- -
- 3D数学基础:向量运算
- 17分钟过桥,过桥最短时间问题
- 判断IP是否在IP段内
- Micropython加速物联网开发8 - 2G网络TCP通信
- Bootloader和Linux启动过程总结
- iapp教程从入门到精通全部,iapp怎么做软件教程
- 2019浙江ACM省赛部分题解-ABDEFGHIJK
- RSA生成公私钥并加解密
- Android wifi PNO扫描流程(Andriod O)
- Ubuntu下有线连接开无线WIFI的3种方式
- Nexus的安装和应用
热门文章
- JAVA的网络编程【转】
- sharepoint 2010 使用WinForm获取 SPSite对象
- Wireshark数据分析IP
- Mysql 日期、字符串、时间戳互转
- Vue2.0 传值方式
- 微信小程序使用template模板
- 记录一个layui框架之自定义模块出现的问题
- error: undefined reference to 'cv::_OutputArray::_OutputArray(std::__ndk1
- Vs工程高版本向低版本迁移
- SLAM: 图像角点检测的Fast算法(时间阈值实验)