二叉搜索树、平衡二叉搜索树和红黑树
文章目录
- 一. 二叉搜索树(Binary Sort Tree)
- 二. 二叉平衡搜索树(AVL)
- 三. 红黑树
一. 二叉搜索树(Binary Sort Tree)
二叉搜索树,又称为二叉排序树(二叉查找树),它或许是一棵空树,或许是具有一下性质的二叉树:
1.若它的左子树不为空,则左子树上所有的节点的值小于根节点的值
2.若它的右子树不为空,则右子树上所有的节点的值都大于根节点的值
3.它的左右子树也分别是二叉搜索树
二叉搜索树的这种特性,使得我们在此二叉树上查找某个值就很方便了,从根节点开始,若要寻找的值小于根节点的值,则在左子树上去找,反之则去右子树查找,直到找到与值相同的节点。插入节点也是一样的道理,从根节点从发,所要插入的值,若小于根节点则去左子树寻找该节点所对应的位置,反之则去右子树寻找,直到找到该节点合适的位置。
二. 二叉平衡搜索树(AVL)
前面提到二叉搜索树,二叉搜索树的特性便于我们进行查找插入删除等一系列操作,其时间复杂度为O(logn)
,但是遇见最差的情况,比如以下这棵树:
这棵树,说是树,其实已经退化成链表了,但从概念上来看,它仍是一棵二叉搜索树,只要我们按照逐次增大,如1、2、3、4、5、6的顺序构造一棵二叉搜索树,如上图。那么插入的时间复杂度就变成了O(n)
,导致这种糟糕的情况原因是因为这棵树极其不平衡,右树的重量远大于左树,因此提出平衡二叉搜索树的结构,称为AVL树。
平衡二叉树,它能保持二叉树的高度平衡,降低二叉树的高度,减少树的平均查找长度。
AVL树的性质:
1. 左子树与右子树高度之差的绝对值不超过1
2. 树的每个左子树和右子树都是AVL树
3. 每一个节点都有一个平衡因子(balance factor),任一节点的平衡因子是-1,0,1(每一个节点的平衡因子=右子树高度-左子树高度)
做到了这点,这棵树看起来就比较平衡了,那么如何生成一棵AVL树呢?算法相对来说复杂,随着新节点的加入,树自动调整自身结构,达到新的平衡状态,这就是我们想要的AVL树。我们分析下,为什么树会失衡?是由于插入了一个新的元素。
在AVL树中,插入一个节点的过程如下:
AVL树插入节点:
1. AVL树首先是二叉搜索树,我们要根据二叉搜索树的插入节点方式进行插入
2. AVL树有判断该树是否平衡的因子,我们要根据平衡因子来对树进行选择调整
具体步骤:
1. 判断该树是不是NULL,若为NULL,直接插入
2. 若不为NULL, 找到要插入节点的位置(用pParent标记双亲,方便插入节点)pCur
3. 插入节点pCur
4. 更新pParent的平衡因子,然后判断该树是否需要调整a.若更新后pParent平衡因子为0的话,pParent在插入之前只有左孩子或者右孩子,此时树的高度不变,该树仍然为AVL树。b.若更新后的pParent平衡因子为1或者-1的话,pParent在插入节点前是叶子节点,此时树的高度可能发生改变,我们需要从pParent节点开始向上判断调整其祖先节点。c.若平衡因子不满足上面的俩种情况,说明该树已经不平衡,需要调整,具体情况见下面,局部调整完后,上面的树已经满足AVL树,此时退出即可。
(在下图中,c)插入节点后,调整平衡因子 -> 插入节点之后->(2)最后一个图,其Parent的bf应为1)
插入节点代码实现如下:
template <class K,class V>
bool AVLTree<K, V>::AVLInsert(K key, V val){//1.根节点为空,直接插入if (_root == NULL) {_root = new Node(key, val);return true;}//2.根节点不为空else{Node* cur = _root;Node* parent =NULL;//a)找到要插入节点的位置while (cur) {parent = cur;if (cur->_key > key)cur = cur->_left;else if (cur->_key < key)cur = cur->_right;elsereturn false; //不允许出现重复元素的节点}//b)插入新节点cur = new Node(key, val);if (parent->_key>key){parent->_left = cur;cur->_parent = parent;}else{parent->_right = cur;cur->_parent = parent;}//c)插入完成后,调整平衡因子while (parent){if (cur == parent->_left)//插入节点在左子树父节点bf--,反之++parent->_bf--;elseparent->_bf++;//1)插入新节点后,parent->bf==0;说明高度没变,平衡,返回if (parent->_bf == 0)break;//2)插入节点后parent->_bf==-1||parent->_bf==1;说明子树高度改变,则继续向上调整else if (parent->_bf == -1 || parent->_bf == 1){cur = parent;parent = parent->_parent;}//3)插入节点后parent->_bf==-2||parent->_bf==2;说明已经不平衡,需要旋转else{if (parent->_bf == 2){if (cur->_bf == 1)RotateL(parent);else// (cur->_bf == -1)RotateRL(parent);}else//parent->_bf == -2 {if (cur->_bf == -1)RotateR(parent);else// (cur->_bf == 1)RotateLR(parent);}break;}}//end while (parent)return true;}
}
当树不平衡时,我们需要做出旋转调整,有四种调整方法,分别为:1. 左单旋 2.右单旋 3.左右单旋 4.右左单旋, 具体调整方法见:https://blog.csdn.net/tanrui519521/article/details/80935348
三. 红黑树
红黑树是自平衡二叉树中的一种,在插入元素时,二叉树会自动调整元素的位置,使树的倆叉维持平衡,红黑树最普遍的用途就是用来实现关联数组。
红黑树遵守5个基本命题:
1.节点是红色或者黑色;
2.根是黑色;
3.所有叶子都是黑色(叶子是NIL节点,空节点);
4.每个红色节点的俩个子节点都是黑色。(从每个叶子到根的所有路径上不能有俩个连续的红色节点);
5.从任一节点到其每个叶子的所有简单路径都包含相同的黑色节点。
注意到命题5,“从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点”,这一点就保证了,红黑树的树高由于每个分支上黑色节点数目一定而维持平衡。
二叉搜索树、平衡二叉搜索树和红黑树相关推荐
- 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
原文:http://blog.csdn.net/sup_heaven/article/details/39313731 数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B ...
- 【算法导论】 二叉搜索树、AVL树、和红黑树
二叉搜索树 二叉搜索树是一颗二叉树或一颗空树且满足以下性质: 1)根节点 x的key值大于任意左子树上节点的key值,小于右子树上任意节点的key值 : 2)其左右子树也分别是一颗二叉搜索树. 使用二 ...
- 二叉树、二叉搜索树,平衡二叉树(旋转)红黑树(红黑规则)
文章目录 3.数据结构 3.1二叉树[理解] 3.2 二叉查找树[理解] 3.3平衡二叉树[理解] 3.4 红黑树[理解] 3.数据结构 3.1二叉树[理解] 二叉树的特点 二叉树中,任意一个节点的度 ...
- 《恋上数据结构第1季》平衡二叉搜索树、AVL树
AVL树 二叉搜索树缺点分析 改进二叉搜索树 平衡(Balance) 理想平衡 如何改进二叉搜索树? 平衡二叉搜索树(Balanced Binary Search Tree) AVL树 BST 对比 ...
- 种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
虽然今天不是植树节,但是我今天想种树. 文章目录 树,什么是树? 二叉树 定义 二叉树的创建 二叉树的前中后序遍历 前序遍历: 中序遍历 后序遍历 已知前序.中序遍历结果,还原二叉树 已知后序.中序遍 ...
- 【数据结构与算法图文动画详解】终于可以彻底弄懂:红黑树、B-树、B+树、B*树、满二叉树、完全二叉树、平衡二叉树、二叉搜索树...
1.树简介 1.1基本概念 树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构.没有结点的树称为空(null或empty)树.一棵非空的树包括一个根结点,还(很可能)有多个附加 ...
- 二叉平衡树 之 红黑树 (手动模拟实现)
目录 1.红黑树的概念 2.红黑树的性质 3.红黑树节点的定义 4.红黑树的插入 5.红黑树验证 代码汇总 6.红黑树的删除(了解) 7.红黑树的应用 8.红黑树 VS AVL树 1.红黑树的概念 红 ...
- 高阶数据结构 —— 红黑树(较平衡搜索树)
文章目录 1. 红黑树的概念 1.1 红黑树的性质 1.2 红黑树效率的分析 2. 红黑树的旋转 2.1 情况一 2.2 情况二 2.3 情况三 2.4 对以上三种情况的总结 3. 红黑树的实现 3. ...
- 算法学习二,红黑树查找算法
二叉查找树,对于大多数情况下的查找和插入在效率上来说是没有问题的,但是他在最差的情况下效率比较低. 红黑树保证在最坏的情况下插入和查找效率都能保证在对数(Log(n))的时间复杂度内完成. 1.红黑树 ...
- 太极定二仪,清浊始以形:红黑树的实现和性质
我们在前面的章节中讲述了平衡二叉查找树,也就是叶节点高度差的绝对值不超过 1,并且左右两个子树都是一颗平衡树.最早被发明的是平衡二叉查找树是 AVL 树,后面红黑树才被发明. AVL 树在每次的插入和 ...
最新文章
- liunx 下su 和sudo 的区别
- Tomcat下的work目录
- 实例比较虚幻引擎4与光线追踪渲染
- 再一次证明了普通的U盘和SD(TF)卡的不可靠
- Linux---生产者与消费者模型
- 算法导论 思考题1-1
- Java 数据库编程专栏 目录
- 隐藏手机号码中间四位程序python_Excel快速将手机号码中间四位数字隐藏
- 为什么CTO、技术总监、架构师都不写代码,还这么厉害
- HTML5浪漫生日祝福电子贺卡网页模板(HTML5+CSS3+JS)_520表白/七夕情人节表白/告白网页制作/生日快乐html模板...
- Bundle Adjustment算法详解资源汇总
- 腾讯开源Spring Cloud Tencent 是什么
- 《九日集训》(第一讲)函数
- 第二章 java语言基础
- mysql汉字转拼音首字母_MySQL中文汉字转拼音的自定义函数和使用实例(首字的首字母)...
- 湖北师范大学----操作系统实训(c语言)
- 转:typedef的用法
- Linux中chkconfig工具详解(世间有许多美好的东西,但真正属于自己的却并不多)
- 深度强化学习+启发人类的决策智能,专访一家有愿景的中国企业「启元世界」...
- python数据分析用什么软件