1.1 概念

平衡二叉树就是为了让二叉搜索树的平均查找长度更短,时间复杂度更靠近logN,如果一个二叉搜索树不平衡了就会出现图1情况,完全变成一个数组,时间复杂度也变为了O(N)。
平衡因子:平衡因子就是针对于树中某一结点,它的左子树高度减去右子树的高度所得结果就是它的平衡因子,如果这个平衡因子的绝对值等于2的话,那么这个树就认为出现了不平衡状况,我们就需要修正这个树,缩小它的平衡因子,缩小平衡因子,也就是让树的左右两端高度更均匀平衡,让高度越靠近log2N+1(N个结点构成的二叉树的高度)。

查找长度:查找长度就是查找运算中需要比较的次数,树的高度越小,查找长度就越小,查找效率就越高。它的定义如下:

n为查找表中元素个数,Pi为查找第i个元素的概率,通常假设每个元素查找概率相同,Pi=1/n,Ci是找到第i个元素的比较次数,显然AVL树中每个节点的比较次数与它所在的层数有关,AVL树本质还是二叉搜索树,二叉搜索树又与线性二分查找一样。
这个集合中,找到每个数的概率都相同,为1/9,第一次查找,就是数组中间那个元素也就是5,第二次查找,有两个方向,向右或者向左指向2或者7,第三次查找有四种可能(1 or 3 or 6 or 8 ) ,第四次有两种可能(4 or 9) ,于是可以算出期望1x1/9+2x2/9+3x4/9+4x2/9=25/9,也就是我们给出一个数,平均要比较两次就能找到,将这个数组抽象为二叉搜索树,通过查找长度公式也能得出这棵树的平均查找长度是25/9。

1.2 修正树,缩小平衡因子的方法

第一种(左旋)
如果插入一个结点(插入点)到另一个结点A的左儿子的左子树而导致树失衡的话,也就是三点连成一条直线(A,A左儿子,插入点),那么我们采用左旋来解决这种情况,我们旋转时以谁为支点,旋转它的子树呢?是以最先发现树不平衡的那位结点,也就是从下往上,第一个平衡因子为2的那个结点。

首先8肯定是最先发现树不平衡的结点,此时以8为支点,将它的子树向左(顺时针)移动,想象着把他它的子树装进麻袋里看作一个整体来进行移动,最后移动到位置后再拆开,此时树结构会发生变化,由于5结点的right指向了8,6这个点变得孤立无援,但由于树结构发生变化,点8的left是空着的,于是就让支点8的left的来指向它。
左旋模板


第二种(右旋)
如果插入一个结点(插入点)到另一个结点A的右儿子的右子树而导致树失衡的话,也就是三点连成一条直线(A,A右儿子,插入点),那么我们采用左旋来解决这种情况。
右旋模板

可以看见A与A的右儿子B,以及插入点,这三点构成向右的一条直线


第三种 左右旋:如果插入一个结点(插入点)到另一个结点A的左儿子的右子树而导致树失衡的话,也就是三点连不成一条直线(A,A左儿子,插入点),那么我们采用左右旋来解决这种情况,左右旋实际就是以A的左儿子为支点对它的右子树进行一次右旋,然后以A为支点对它左子树进行一次左旋


第四种 右左旋:如果插入一个结点(插入点)到另一个结点A的右儿子的左子树而导致树失衡的话,也就是三点连不成一条直线(A,A右儿子,插入点),那么我们采用右左旋来解决这种情况,右左旋实际就是以A的右儿子为支点对它的左子树进行一次左旋,然后以A为支点对它右子树进行一次右旋


java代码实现

class AVLTree {Tree root;public void Insert(int Data){root=Tree.InsertNode(root,Data);}public void Inorder(){Tree.Inorder(root);}public int Height(){return Tree.MaxHeight(root);}
}public class Tree {Tree left;Tree right;int Data;public Tree(int Data){this.Data=Data;}public  static Tree InsertNode(Tree root, int Data){if(root==null){Tree node = new Tree(Data);return node;}else {if (Data > root.Data) {//插入的是右子树root.right = InsertNode(root.right, Data);if(MaxHeight(root.left)-MaxHeight(root.right)==-2){if(Data>root.right.Data)//右旋root=rightTrans(root);elseroot=right_left_Trans(root);}} else if (Data <= root.Data) {//插入的左子树root.left = InsertNode(root.left, Data);if(MaxHeight(root.left)-MaxHeight(root.right)==2){if(Data<root.left.Data)//左旋root=rightTrans(root);elseroot=left_right_Trans(root);}}}return root;}public static Tree Delete(Tree node, int Data){if(node==null){return null;   //未找到}//先找到要删除的节点if(Data>node.Data){node.right = Delete(node.right,Data);}elseif(Data<node.Data){node.left = Delete(node.left,Data);}else{//找到了if(node.left!=null && node.right!=null){node.Data=findInsteadNode(node.left);Delete(node.left,Data);}else{if(node.right!=null)node=node.right;elseif(node.left!=null)node=node.left;elsenode=null;}}return node;}public static int findInsteadNode(Tree node){if(node.right!=null)return findInsteadNode(node.right);elsereturn node.Data;}public static void Inorder(Tree node){if(node!=null){Inorder(node.left);System.out.println(node.Data+" ");Inorder(node.right);}}//高度计算函数public static int MaxHeight(Tree node){int leftHeight,rightHeight;if(node!=null){leftHeight=MaxHeight(node.left);rightHeight=MaxHeight(node.right);return (leftHeight>rightHeight ?leftHeight:rightHeight)+1;}return 0;}//右旋public static Tree rightTrans(Tree A){Tree B=A.right;A.right=B.left;B.left=A;return B;}//左右旋public static Tree left_right_Trans(Tree A){Tree B=A.left;A.left=rightTrans(B);return leftTrans(A);}//左旋public static Tree leftTrans(Tree A){Tree B=A.left;A.left=B.right;B.right=A;return B;}//右左旋public static Tree right_left_Trans(Tree A){Tree B=A.right;A.right=leftTrans(B);return rightTrans(A);}public static void main(String[] args) {AVLTree avlTree = new AVLTree();avlTree.Insert(10);avlTree.Insert(15);avlTree.Insert(5);avlTree.Insert(3);avlTree.Insert(8);avlTree.Insert(6);}
}

AVL树(平衡二叉树)讲解,入门篇,适合新手观看相关推荐

  1. Yocto系列讲解[入门篇] 1 - 快速入门熟悉Yocto的构建

    By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! ...

  2. 自学Web前端开发学习讲解 – 入门篇

    很多人都对web前端感兴趣,这一期主要聊关于如何入门学习Web前端开发的过程分享,此篇适合想入门初学者,大佬就不用看了.主要内容是以本人这一路自学web前端的一些经验和建议,学习哪些知识,以及如何正确 ...

  3. java技术分享主题_Java开发入门:适合新手练手的Java项目(附源码下载)

    Java作为一门古老的语言,已有20年左右的历史,这在发展日新月异的技术圈可以说是一个神话.虽然不少人曾抱怨Java语言就像老太太的裹脚布,又臭又长,有时写了500行都不能表达程序员的意图. 但从市场 ...

  4. 注册Github账号详细教程【超详细篇 适合新手入门】

    目录 一.GitHub的简介 1.大概介绍 2.详细介绍 二.如何注册自己的GitHub账户 1.进入github的官网 2.点击右上角注册按钮sign up,来到注册页面 3.在光标处输入自己的邮箱 ...

  5. 一篇适合新手的深度学习综述

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自|人工智能与算法学习 这篇综述论文列举出了近年来深度学习的重 ...

  6. 史上最全的App推广入门篇【新手必备】

    说到移动App的推广,高手一般都有自己一套成熟的推广套路,运用起来也是驾轻就熟,但是对于新手来说,在创业团队初始阶段,产品不成熟.渠道不成熟.团队不成熟.预算不充足.用户没粘性的情况下,该怎么做推广呢 ...

  7. 5天学习MYSQL数据库第一天剩余全部笔记(超级详细的mysql入门笔记适合新手反复看加深记忆)

    这是关于五天学习MYSQL数据库的笔记,如果想要观看视频可以访问(视频链接(b站) 或者访问视频链接 之前的笔记已经记到了1.3的mysql基本介绍,接下来主要是: 2.1MySQL服务端框架 一. ...

  8. 二叉搜索树(创建,插入,删除):基础篇,适合新手观看。

    1.1 二叉搜索树的插入 二叉搜索树的概念相信大家都很清楚,无非就是左小右大 创建二叉搜索树,其实就是多次调用二叉搜索树的插入方法,所以首先我们来讲讲如何插入节点到二叉搜索树里,假设一颗二叉搜索树如下 ...

  9. css做名单,css基础教程:2021年适合新手的7个CSS入门教程推荐

    上一篇我们向同学们推荐了5个html入门教程,本篇我们继续向同学们精选推荐一些适合新手学习的CSS基础入门教程,欢迎学习! 首先我们来介绍什么是CSS?以及CSS的作用 CSS 是一种标准样式表语言, ...

最新文章

  1. 杨老师课堂_Java核心技术下之控制台模拟文件管理器案例
  2. UNIX/LINUX程序设计教程(1)-- 获取系统信息
  3. 人人都应该知道的身体小窍门!
  4. THUWC 2018(游记)
  5. http://www.cnblogs.com/langjt/p/4281477.html
  6. VS2010 VS2012版最常用的快捷键
  7. 带鉴权信息的SIP呼叫
  8. Hexo框架下用NexT(v7.0+)主题美化博客
  9. 如何注册google账户呢?
  10. 透过CES看国产手机市场变动 “中华酷联”要调位
  11. 思维导图 · App的商业模式:如何寻找商业化
  12. 火狐浏览器怎么设置打开书签的时候在新标签页打开
  13. PHP是单线程还是多线程?
  14. 颜色选择器---Kodu少儿编程第九天
  15. 查看自己电脑的处理器和操作系统的位数
  16. Service unavailable是什么意思?是网站有问题吗?怎么解决?
  17. TOPSIS和熵权法的应用(Matlab实现,包括数据预处理)
  18. DeepFM理论与实践
  19. Qt图形视图QGraphicsItem类
  20. 浙江省 教师资格证 岗前培训考试 浙江高培中心报名系统

热门文章

  1. python闭环最短路径_深度学习经典算法 | 蚁群算法解析
  2. d类功放芯片_应用于无滤波级D类音频功放的新型死区时间控制系统
  3. android 骨骼动画库,cocos creator spine骨骼动画组件使用
  4. 浏览器渲染机制面试_【前端面试必考题】页面渲染机制(一)
  5. 1300多名硕博研究生被清退!全都是活该?真相有时候比表面更让人无奈......
  6. 身家4400亿美元的他,吃低于3美元的早餐,和2个老婆同居28年!
  7. 遭央视曝光的“AI算命”,背后竟然隐藏了一个价值千亿的市场!?
  8. 35岁老程序员因身体原因没加班,老板:不想干就滚蛋
  9. 干货|MIT线性代数课程精细笔记[第一课]
  10. 提升代码可读性的 10 个技巧