AVL树详解¶
转自:AVL树(一)之 图文解析 和 C语言的实现(本文图片及文字描述部分转自该文) 参考:邓俊辉 的数据结构,部分图片来自该资料
代码是C#写的
AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的。 它是最先发明的自平衡二叉查找树,也被称为高度平衡树。相比于"二叉查找树",它的特点是:AVL树中任何节点的两个子树的高度最大差别为1。(树的高度:树中结点的最大层次)
上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1;而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而节点8的高度是1)。
AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。 如果在AVL树中插入或删除节点后,使得高度之差大于1。此时,AVL树的平衡状态就被破坏,它就不再是一棵二叉树;为了让它重新维持在一个平衡状态,就需要对其进行旋转处理。学AVL树,重点的地方也就是它的旋转算法
首先要明确的是,== 平衡二叉树是一棵二叉排序树,它的出现是为了解决普通二叉排序树(普通二叉排序树)不平衡的问题。如图,在插入结点之前首先要查找插入位置,假如要在5结点后插入,普通二叉排序树需要比较五次,而平衡二叉树只需要比较三次。假如结点规模进一步加大,效率提升也会更明显。 (图片来自https://blog.csdn.net/m0_38036210/article/details/100517125)
0X01 节点和树的定义¶
1. 节点的定义¶
2. 树的定义¶
3.树的高度¶
空的二叉树的高度是0,非空树只有一个节点根节点高度为1等等
0X02 单旋和双旋¶
前面说过,如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。
2.1 zag单旋(左旋)¶
如果说节点g失去平衡,g的右孩子p高度比左孩子高,且右孩子p的右孩子v高度比右孩子p的左孩子高度高,那么进行逆时针旋转进行调整高度
假设在子树v中插入某个节点x(虚线连接部分,其中一个节点对应x,另一个为空节点),这时候v节点是平衡的,p节点也是平衡,但是g节点不平衡,g的右孩子高度减去g的做孩子高度等于2,需要对g节点进行调整,这时候以g为轴进行逆时针旋转(左旋),调整后从a子树变为b子树;从而达到子树的平衡, 而且高度未变化,所以该子树平衡后,父节点及除子树的其他树的部分都是平衡的。
旋转代码
2.2 zig单旋(右旋)¶
假设在子树v中插入某个节点x(虚线连接部分,其中一个节点对应x,另一个为空节点),这时候v节点是平衡的,p节点也是平衡,但是g节点不平衡,g的右孩子高度减去g的做孩子高度等于-2,需要对g节点进行调整,这时候以g为轴进行顺时针旋转(右旋),调整后从a子树变为b子树;从而达到子树的平衡, 而且高度未变化,所以该子树平衡后,父节点及除子树的其他树的部分都是平衡的。
旋转代码
2.3 zagzig双旋¶
(先逆时针旋转p(zag),后顺时针旋转g(zig))
旋转代码
2.4 zigzag双旋¶
先顺时针旋转p(zig),后逆时针旋转g(zag)
旋转代码
0X03 查找¶
0X04 插入¶
插入节点的代码
0X05 删除¶
删除节点的代码
0X07 打印二叉树代码(C#)¶
打印结果: 打印数值最大3位数
0X07 完整代码(C#)¶
0X08 AVL树测试¶
测试完整代码(github)和完整代码一样 测试插入和删除。测试中对zig、zag、zigzag、zagzig操作在插入时都执行了;删除操作执行了部分操作,剩余可以自己完善测试案例, 测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
0X09 AVL树可视化工具¶
AVL树可视化工具(旧金山大学 (usfca)|数据结构可视化工具)






