平衡二叉树的旋转_平衡二叉树的旋转
一、平衡二叉树的定义
为避免树的高度增长过快,降低二叉树的排序性能,规定在插入和删除二叉树结点时,保证任意结点的左右子树高度差的绝对值不大于1。这样的二叉树被称为平衡二叉树(Balanced Binary Tree)。
二、平衡因子
平衡因子:结点的平衡因子 = 结点的左子树深度 — 结点的右子树深度。若平衡因子的取值为-1、0或1时,该节点是平衡的,否则是不平衡的。
最低不平衡结点:用A表示最低不平衡结点,则A的祖先结点可能有不平衡的,但其所有后代结点都是平衡的。
简单理解为:一个结点的左右子树高度差不超过一,超过一就不平衡,需要进行旋转。
二、LL平衡旋转(右单旋转)
B→根节点,B的右子树成为A的左子树
实现代码:
void rRotate(Node *Parent)//LL { Node *subL = Parent->_pLeft; Node *subLR = subL->_pRight; Parent->_pLeft = subLR; if (subLR)//左单支 subLR->_parent = Parent; subL->_pRight = Parent; Node *pParent = Parent->_parent; Parent->_parent = subL; subL->_parent = pParent; if (NULL == pParent)//Parent是根节点 _pRoot = subL; else if (Parent == pParent->_pLeft) pParent->_pLeft = subL; else pParent->_pRight = subL; //修改平衡因子 subL->_bf = 0; Parent->_bf = 0; }
三、RR旋转(左单旋转)B左上为根,B的左子树成为A的右子树
实现代码:
void lRotate(Node *Parent)//RR { Node *subR = Parent->_pRight; Node *subRL = subR->_pLeft; Parent->_pRight = subRL; if (subRL) subRL->_parent = Parent; subR->_pLeft = Parent; subR->_parent = Parent->_parent; Parent->_parent = subR; Node *pParent = subR->_parent; if (NULL == pParent) _pRoot = subR; else if (Parent == pParent->_pLeft) pParent->_pLeft = subR; else pParent->_pRight = subR; Parent->_bf = 0; subR->_bf = 0; }
四、LR平衡双旋转(先左后右双旋转)由基础旋转组合而来
实现代码:
void lrRotate(Node *Parent)//LR { Node *subL = Parent->_pLeft; Node *subLR = subL->_pRight; int bf = subLR->_bf; lRotate(Parent->_pLeft); rRotate(Parent); if (1 == bf) subL->_bf = -1; else if (-1 == bf) Parent->_bf = 1; subLR->_bf = 0; }
五、RL平衡旋转(先右后左双旋转)组合旋转,可以分为两步进行旋转
实现代码:
void rlRotate(Node *Parent) { Node *subR = Parent->_pRight; Node *subRL = subR->_pLeft; int bf = subRL->_bf; rRotate(Parent->_pRight); lRotate(Parent); if (1 == bf) Parent->_bf = -1; else if (-1 == bf) subR->_bf = 1; subRL->_bf = 0; }
AVL树插入代码:
bool Insert(const K& key, const V& value) { Node *pNew = new Node(key,value); Node *pCur = _pRoot; Node *parent = NULL; if (NULL == _pRoot) { _pRoot = pNew; return true; } while (pCur)//寻找插入位置 { if (key < pCur->_key) { parent = pCur; pCur = pCur->_pLeft; } else if (key > pCur->_key) { parent = pCur; pCur = pCur->_pRight; } else return false; } if (key < parent->_key)//插入元素 parent->_pLeft = pNew; else parent->_pRight = pNew; pNew->_parent = parent; //修改平衡因子 while (parent) { if (pNew == parent->_pLeft) parent->_bf--; else parent->_bf++; if (0 == parent->_bf) return true; else if (1 == parent->_bf || -1 == parent->_bf) { pNew = parent; parent = parent->_parent; } else//2需要进行旋转 { if (-2 == parent->_bf && -1 == pNew->_bf)//LL rRotate(parent); else if (2 == parent->_bf && 1 == pNew->_bf)//RR lRotate(parent); else if (-2 == parent->_bf && 1 == pNew->_bf)//LR lrRotate(parent); else if (2 == parent->_bf && -1 == pNew->_bf)//RL rlRotate(parent); return true; } } return true; }
本文参考算法网平衡二叉树旋转详解,和王道论坛。
平衡二叉树的旋转_平衡二叉树的旋转相关推荐
- 高度平衡二叉树的构建_平衡二叉树 构造方法(绝妙)
构造方法 平衡二叉树 对于二叉查找树,尽管查找.插入及删除操作的平均运行时间为 O(logn) ,但是它们的最差 运行时间都是 O(n), 原因在于对树的形状没有限制. 平衡二叉树又称为 AVL 树, ...
- 高度平衡二叉树的构建_平衡二叉树(AVL)树
1.平衡二叉树定义 是一种二叉排序树(二叉查找树.二叉搜索树),其中每个节点的左子树和右子树的高度差不大于1.(左右子树也是平衡二叉树) 平衡因子BF = 二叉树节点的左子树深度减去右子树深度 = 节 ...
- 高度平衡二叉树的构建_平衡二叉树建立及其增删改查(JAVA)
平衡二叉树:指的是左右子树高度差的绝对值不超过一的二叉排序树. 主要思路:1.用左高度跟右高度代替平衡因子,大于1进行L~调整,小于-1进行R~调整 2.每次插入都通过递归计算一次各结点高度,然后进行 ...
- css3魔方3乘3每层旋转_学习做旋转魔方 (css3)
学习做旋转魔方 (css3) 看到一个帖子做了一个旋转魔方, 想着试着学习练练手. 看着高手的代码按照自己的思路, 码了一下, 记下遇到的一些问题. html 代码片段 3D 魔方 Rubik's C ...
- 平衡二叉树平衡因子怎么计算_平衡二叉树(AVL Tree)旋转机制分析
平衡二叉树(AVL Tree) 概述 AVL树是以二分搜索树(BST)为底层数据结构而实现的,其特性是需要维护AVL的|平衡因子| <= 1 平衡因子 对于一个父节点的左右子树高度差的绝对值需要 ...
- 【数据结构笔记12】平衡二叉树,AVL树,RR旋转/LL旋转/LR旋转/RL旋转,AVL树插入的代码实现
本次笔记内容: 4.2.1 什么是平衡二叉树 4.2.2 平衡二叉树的调整 文章目录 什么是平衡二叉树 评价查找长度ASL 平衡因子(Balance Factor,BF) 平衡二叉树(Balanced ...
- 平衡二叉树及其操作实现_平衡二叉树(AVL树)及C语言实现
上一节介绍如何使用二叉排序树实现动态查找表,本节介绍另外一种实现方式--平衡二叉树.平衡二叉树,又称为 AVL 树.实际上就是遵循以下两个特点的二叉树: 每棵子树中的左子树和右子树的深度差不能超过 1 ...
- c++ 删除二叉树的子树_平衡二叉树
二叉树 二叉数是每个节点最多有两个子树,或者是空树(n=0),或者是由一个根节点及两个互不相交的,分别称为左子树和右子树的二叉树组成. 满二叉树 有两个非空子树(二叉树中的每个结点恰好有两个孩子结点切 ...
- 带父节点的平衡二叉树_平衡二叉树 通俗易懂
平衡二叉树(AVL) 阅读之前请先了解 二叉搜索树 平衡二叉树定义:任意节点的子树的高度差都小于等于 1 1. 为什么使用「平衡二叉树」 二叉树能提高查询的效率 O(logn),但是当你插入 {1,2 ...
最新文章
- 近三月浏览器网页访问量统计
- (需求实战_01)_shell脚本 ftp协议下载文件
- 关于体育的python毕业设计_Python实例13:体育竞技分析
- 什么是java源码文件,什么是字节码文件,初程序的编译和运行
- python 读取合并单元格 视频_Python如何使用xlrd实现读取合并单元格
- c++指针各种用法小结
- 因被曝严重漏洞,Avast紧急禁用其 JavaScript 引擎
- sql server 2000 生成数据库的SQL脚本
- java帮助文档中文怎么下载,看完必懂
- 神舟战神笔记本重做系统
- [Maven实战-许晓斌]-[第二章]-2.5 Eclipse上面安装Maven插件 m2eclipse
- 金蝶/K3Wise 月末结账时候提示:违反违反了PRIMARYKEY约束,PK_POZnvBal,不能在对象POinvBal中插入重复键
- 网络共享计算机无法登录,局域网共享文件夹访问无法出现用户登陆窗口怎么办?...
- android img 文件解包
- Apollo搭建使用
- python日常实用小脚本-用Python编写渗透用小脚本 短小实用
- 深度学习【道路提取】:马萨诸塞州道路数据集分享
- Ubuntu16.04安装有道词典
- leetcode 1833 雪糕的最大数量
- 中富金石老师:中颖电子实现汽车电子芯片生产 开启第二增长曲线