|
6 | 6 | * 创建AVL树(平衡二叉树) |
7 | 7 | */ |
8 | 8 |
|
9 | | -public class AVLTree { |
| 9 | +public class AVLTree<E> { |
| 10 | + Node<E> root; |
| 11 | + /** |
| 12 | + * RH:只有右子节点 |
| 13 | + * LH:只有左子节点 |
| 14 | + * EH:有左右子节点 |
| 15 | + */ |
| 16 | + //左面减右面为负 |
| 17 | + private static final int RH = -1; |
| 18 | + private static final int LH = 1; |
| 19 | + private static final int EH = 0; |
| 20 | + private int size; |
10 | 21 |
|
| 22 | + /** |
| 23 | + * 插入元素 |
| 24 | + * |
| 25 | + * @param element |
| 26 | + * @return |
| 27 | + */ |
| 28 | + public boolean insertElement(E element) { |
| 29 | + Node<E> t = root; |
| 30 | + if (t == null) { |
| 31 | + root = new Node<>(element, null); |
| 32 | + size = 1; |
| 33 | + root.balance = 0; |
| 34 | + return true; |
| 35 | + } else { |
| 36 | + //插入节点 |
| 37 | + int cmp = 0; |
| 38 | + Node<E> parent; |
| 39 | + Comparable<? super E> e = (Comparable<? super E>) element; |
| 40 | + do { |
| 41 | + parent = t; |
| 42 | + cmp = e.compareTo(t.element); |
| 43 | + if (cmp < 0) { |
| 44 | + t = t.left; |
| 45 | + } else if (cmp > 0) { |
| 46 | + t = t.right; |
| 47 | + } else { |
| 48 | + return false; |
| 49 | + } |
| 50 | + } while (t != null); |
| 51 | + Node<E> child = new Node<>(element, parent); |
| 52 | + if (cmp < 0) { |
| 53 | + parent.left = child; |
| 54 | + } else { |
| 55 | + parent.right = child; |
| 56 | + } |
| 57 | + //插入节点 结束 |
| 58 | + //检查平衡因子,回溯查找 |
| 59 | + while (parent != null) { |
| 60 | + //比较当前节点与父节点的大小 |
| 61 | + cmp = e.compareTo(parent.element); |
| 62 | + //根据插入的位置来调整parent |
| 63 | + if (cmp > 0) { |
| 64 | + parent.balance--; |
| 65 | + } else { |
| 66 | + parent.balance++; |
| 67 | + } |
| 68 | + if (parent.balance == 0) { |
| 69 | + break; |
| 70 | + } |
| 71 | + |
| 72 | + if (Math.abs(parent.balance) == 2) { |
| 73 | + fixAfterInsertion(parent); |
| 74 | + break; |
| 75 | + } else { |
| 76 | + parent = parent.parent; |
| 77 | + } |
| 78 | + } |
| 79 | + size++; |
| 80 | + return true; |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + /** |
| 85 | + * @param parent |
| 86 | + */ |
| 87 | + private void fixAfterInsertion(Node<E> parent) { |
| 88 | + if (parent.balance == 2) { |
| 89 | + leftBalance(parent); |
| 90 | + } else if (parent.balance == -1) { |
| 91 | + rightBalance(parent); |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + /** |
| 96 | + * 做平衡操作 |
| 97 | + * |
| 98 | + * @param t |
| 99 | + */ |
| 100 | + public void leftBalance(Node<E> t) { |
| 101 | + Node<E> tl = t.left; |
| 102 | + switch (tl.balance) { |
| 103 | + case LH: |
| 104 | + rightRoate(t); |
| 105 | + tl.balance = EH; |
| 106 | + t.balance = EH; |
| 107 | + break; |
| 108 | + case RH: |
| 109 | + Node<E> tlr = tl.right; |
| 110 | + leftRoate(t.left); |
| 111 | + rightRoate(t); |
| 112 | + switch (tlr.balance) { |
| 113 | + case LH: |
| 114 | + t.balance = RH; |
| 115 | + tl.balance = EH; |
| 116 | + tlr.balance = EH; |
| 117 | + break; |
| 118 | + case RH: |
| 119 | + t.balance = EH; |
| 120 | + tl.balance = LH; |
| 121 | + tlr.balance = EH; |
| 122 | + break; |
| 123 | + case EH: |
| 124 | + t.balance = EH; |
| 125 | + tl.balance = EH; |
| 126 | + tlr.balance = EH; |
| 127 | + break; |
| 128 | + } |
| 129 | + break; |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + /** |
| 134 | + * 右平衡操作 |
| 135 | + * |
| 136 | + * @param t |
| 137 | + */ |
| 138 | + public void rightBalance(Node<E> t) { |
| 139 | + Node<E> tr = t.right; |
| 140 | + switch (tr.balance) { |
| 141 | + case RH: |
| 142 | + //根节点的右子树的右子树上插入 |
| 143 | + leftRoate(t); |
| 144 | + t.balance = EH; |
| 145 | + tr.balance = EH; |
| 146 | + |
| 147 | + break; |
| 148 | + case LH: |
| 149 | + //根节点的右子树的左子树上插入 |
| 150 | + Node<E> trl = tr.left; |
| 151 | + rightRoate(t.right); |
| 152 | + leftRoate(t); |
| 153 | + switch (trl.balance) { |
| 154 | + case RH: |
| 155 | + t.balance = LH; |
| 156 | + tr.balance = EH; |
| 157 | + trl.balance = EH; |
| 158 | + break; |
| 159 | + case LH: |
| 160 | + t.balance = EH; |
| 161 | + tr.balance = RH; |
| 162 | + trl.balance = EH; |
| 163 | + break; |
| 164 | + case EH: |
| 165 | + t.balance = EH; |
| 166 | + tr.balance = EH; |
| 167 | + trl.balance = EH; |
| 168 | + break; |
| 169 | + } |
| 170 | + break; |
| 171 | + case EH: |
| 172 | + break; |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + /** |
| 177 | + * 右旋算法 |
| 178 | + * |
| 179 | + * @param node |
| 180 | + */ |
| 181 | + public void rightRoate(Node<E> node) { |
| 182 | + if (node != null) { |
| 183 | + Node<E> nodel = node.left; |
| 184 | + node.left = node.right; |
| 185 | + // |
| 186 | + if (nodel.right != null) { |
| 187 | + nodel.right.parent = node; |
| 188 | + } |
| 189 | + // |
| 190 | + nodel.parent = node.parent; |
| 191 | + if (node.parent == null) { |
| 192 | + root = nodel; |
| 193 | + } else { |
| 194 | + if (node.parent.left == node) { |
| 195 | + node.parent.left = nodel; |
| 196 | + } else if (node.parent.right == node) { |
| 197 | + node.parent.right = nodel; |
| 198 | + } |
| 199 | + } |
| 200 | + nodel.right = node; |
| 201 | + node.parent = nodel; |
| 202 | + } |
| 203 | + } |
| 204 | + |
| 205 | + /** |
| 206 | + * 左旋算法 |
| 207 | + * |
| 208 | + * @param node |
| 209 | + */ |
| 210 | + public void leftRoate(Node<E> node) { |
| 211 | + if (node != null) { |
| 212 | + //node的右子树节点 |
| 213 | + Node<E> nodeR = node.right; |
| 214 | + //1.把node右子树的左节点指定给node的右子树 |
| 215 | + node.right = nodeR.left; |
| 216 | + if (nodeR.left != null) { |
| 217 | + nodeR.left.parent = node; |
| 218 | + } |
| 219 | + //2.把node制定给node右子树的左节点 |
| 220 | + nodeR.left = node; |
| 221 | + //3.将node右子树的parent指定 |
| 222 | + if (node.parent == null) { |
| 223 | + root = nodeR; |
| 224 | + } else { |
| 225 | + if (node.parent.left == node) { |
| 226 | + node.parent.left = nodeR; |
| 227 | + } else if (node.parent.right == node) { |
| 228 | + node.parent.right = nodeR; |
| 229 | + } |
| 230 | + } |
| 231 | + nodeR.parent = node.parent; |
| 232 | + } |
| 233 | + } |
| 234 | + |
| 235 | + public class Node<E> { |
| 236 | + E element; |
| 237 | + //平衡因子(左子树深度减右子树深度) |
| 238 | + int balance = 0; |
| 239 | + Node<E> left; |
| 240 | + Node<E> right; |
| 241 | + Node<E> parent; |
| 242 | + |
| 243 | + public Node(E element, Node<E> parent) { |
| 244 | + this.element = element; |
| 245 | + this.parent = parent; |
| 246 | + } |
| 247 | + } |
11 | 248 | } |
0 commit comments