• 数据结构(6)树形结构——平衡二叉树(JAVA代码实现)


    目录

    6.1.概述

    6.2.AVL树

    6.2.1.概述

    6.2.2.旋转

    1.RR旋转

     2.LL旋转

    3.LR旋转

    4.RL旋转

     6.2.3.代码实现


    6.1.概述

    二叉搜索树存在一个问题,就是树的姿态和数据的插入顺序是有关系的,有时候树会变成某一边的子树高度过高,甚至直接退化成斜二叉树,使得查找从二分查找跌落为顺序查找:

    保证任意结点左右子树的高度一致,便可以保证树的查询效率为最优,但是此种情况过于理想,难以达到,因此允许左右子树的高度间存在差异,于是出现了平衡二叉树,即任意结点左右子树高度差不超过1:

    每次操作后出现有结点的左右子树高度差超过1的情况时,树会自己进行调整姿态,重新达到平衡。

    平衡二叉树只是一种思想,有很多种实现,常见的实现有红黑树、AVL、Treap、伸展树等。

    6.2.AVL树

    6.2.1.概述

    AVL是出现的第一种平衡二叉树,每当插入元素,造成AVL树的不平衡后,它会通过旋转的方式调整最小不平衡树,从而将树调整平衡。插入后造成不平衡的元素叫“破坏者”,最小不平衡树的根节点叫“被破坏者”。

    最小不平衡树,即从高度差超过1的两条分支开始向上找,找到它们的第一个共同父结点,以这个父节点为根结点的子树就是最小不平衡树。

    AVL的旋转有四种:

    • RR旋转
    • LL旋转
    • LR旋转
    • RL旋转

    6.2.2.旋转

    1.RR旋转

    “破坏者”在右子树的右子树,执行RR旋转,将“被破坏者”的右孩子提为根节点,该右孩子的左子树移植为“被破坏者”的右子树。

     2.LL旋转

    “破坏者”在左子树的左子树,就执行LL旋转,将“被破坏者”压为“破坏者”父节点的右孩子,“破坏者”父节点往上走一层。

    3.LR旋转

    破坏者在左子树的右子树,就执行LR旋转,步骤和LL旋转相同,将“被破坏者”压为“破坏者”父节点的右孩子,“破坏者”父节点往上走一层。

    4.RL旋转

    破坏者在右子树的左子树执行RL旋转,调整被破坏者,被破坏者的R,以及被破坏者R的L(这里可能有点晕,其实仔细观察会发现其实就是契合右子树的左子树这个位置关系。),被破坏者的R提上,被破坏者的R的L不变。

     6.2.3.代码实现

    1. public class AvlTreeextends Comparablesuper T>> {
    2. private AvlNode root;
    3. public void insert(T x) {
    4. root = insert(x, root);
    5. }
    6. public void remove(T x) {
    7. root = remove(x, root);
    8. }
    9. public T findMin() {
    10. return findMin(root).element;
    11. }
    12. public void makeEmpty() {
    13. root = null;
    14. }
    15. public boolean isEmpty() {
    16. return root == null;
    17. }
    18. /**
    19. * 添加节点
    20. *
    21. * @param x 插入节点
    22. * @param t 父节点
    23. */
    24. private AvlNode insert(T x, AvlNode t) {
    25. //如果根节点为空,则当前x节点为根及诶单
    26. if (null == t) {
    27. return new AvlNode(x);
    28. }
    29. int compareResult = x.compareTo(t.element);
    30. //小于当前根节点 将x插入根节点的左边
    31. if (compareResult < 0) {
    32. t.left = insert(x, t.left);
    33. } else if (compareResult > 0) {
    34. //大于当前根节点 将x插入根节点的右边
    35. t.right = insert(x, t.right);
    36. } else {
    37. }
    38. return balance(t);
    39. }
    40. private static final int ALLOWED_IMBALANCE = 1;
    41. private AvlNode balance(AvlNode t) {
    42. if (t == null) {
    43. return t;
    44. }
    45. if (height(t.left) - height(t.right) > ALLOWED_IMBALANCE) {
    46. if (height(t.left.left) >= height(t.left.right)) {
    47. t = rotateWithLeftChild(t);
    48. } else {
    49. t = doubleWithLeftChild(t);
    50. }
    51. } else if (height(t.right) - height(t.left) > ALLOWED_IMBALANCE) {
    52. if (height(t.right.right) >= height(t.right.left)) {
    53. t = rotateWithRightChild(t);
    54. } else {
    55. t = doubleWithRightChild(t);
    56. }
    57. }
    58. t.height = Math.max(height(t.left), height(t.right)) + 1;
    59. return t;
    60. }
    61. private AvlNode doubleWithRightChild(AvlNode k3) {
    62. k3.right = rotateWithLeftChild(k3.right);
    63. return rotateWithRightChild(k3);
    64. }
    65. private AvlNode rotateWithRightChild(AvlNode k2) {
    66. AvlNode k1 = k2.right;
    67. k2.right = k1.left;
    68. k1.left = k2;
    69. k2.height = Math.max(height(k2.right), height(k2.left)) + 1;
    70. k1.height = Math.max(height(k1.right), k2.height) + 1;
    71. return k1;
    72. }
    73. private AvlNode doubleWithLeftChild(AvlNode k3) {
    74. k3.left = rotateWithRightChild(k3.left);
    75. return rotateWithLeftChild(k3);
    76. }
    77. private AvlNode rotateWithLeftChild(AvlNode k2) {
    78. AvlNode k1 = k2.left;
    79. k2.left = k1.right;
    80. k1.right = k2;
    81. k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
    82. k1.height = Math.max(height(k1.left), k2.height) + 1;
    83. return k1;
    84. }
    85. private int height(AvlNode t) {
    86. return t == null ? -1 : t.height;
    87. }
    88. /**
    89. * 删除节点
    90. *
    91. * @param x 节点
    92. * @param t 父节点
    93. */
    94. private AvlNode remove(T x, AvlNode t) {
    95. if (null == t) {
    96. return t;
    97. }
    98. int compareResult = x.compareTo(t.element);
    99. //小于当前根节点
    100. if (compareResult < 0) {
    101. t.left = remove(x, t.left);
    102. } else if (compareResult > 0) {
    103. //大于当前根节点
    104. t.right = remove(x, t.right);
    105. } else if (t.left != null && t.right != null) {
    106. //找到右边最小的节点
    107. t.element = findMin(t.right).element;
    108. //当前节点的右边等于原节点右边删除已经被选为的替代节点
    109. t.right = remove(t.element, t.right);
    110. } else {
    111. t = (t.left != null) ? t.left : t.right;
    112. }
    113. return balance(t);
    114. }
    115. /**
    116. * 找最小节点
    117. *
    118. * @param root 根节点
    119. */
    120. private AvlNode findMin(AvlNode root) {
    121. if (root == null) {
    122. return null;
    123. } else if (root.left == null) {
    124. return root;
    125. }
    126. return findMin(root.left);
    127. }
    128. /**
    129. * 找最大节点
    130. *
    131. * @param root 根节点
    132. */
    133. private AvlNode findMax(AvlNode root) {
    134. if (root == null) {
    135. return null;
    136. } else if (root.right == null) {
    137. return root;
    138. } else {
    139. return findMax(root.right);
    140. }
    141. }
    142. public void printTree() {
    143. if (isEmpty()) {
    144. System.out.println("节点为空");
    145. } else {
    146. printTree(root);
    147. }
    148. }
    149. public void printTree(AvlNode root) {
    150. if (root != null) {
    151. System.out.print(root.element);
    152. if (null != root.left) {
    153. System.out.print("左边节点" + root.left.element);
    154. }
    155. if (null != root.right) {
    156. System.out.print("右边节点" + root.right.element);
    157. }
    158. System.out.println();
    159. printTree(root.left);
    160. printTree(root.right);
    161. }
    162. }
    163. }

  • 相关阅读:
    厉害了,腾讯内部都用的Spring+MyBatis源码手册,实战理论两不误
    WebShpereMQ配置与测试
    MATLAB基本绘图功能使用
    前端开发之webpack
    【软考】9.5 排序算法原理
    【抢先体验】开通使用 ChatGPT 语音版功能保姆级教程
    计数排序(Counting Sort)详解
    【数据结构基础】时间复杂度和空间复杂度
    计算机网络复习第二章 物理层
    Arduino开发实例-多机CAN-Bus通信(基于MCP2515)
  • 原文地址:https://blog.csdn.net/Joker_ZJN/article/details/128085597