AVL树的定义
一种自平衡二叉查找树,中面向内存的数据结构。
二叉搜索树T为AVL树的满足条件为:
- T是空树
- T若不是空树,则TL、TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高度与节点的右子树高度差的绝对值小于等于1)
说明
AVL树的实现类为AVLTree继承自前篇中的二叉搜索树BTreeSort ,AVL树的节点类为AVLNode继承自二叉树节点类BTreeNode。
实现代码
AVL树节点定义
1 | public class AVLNode extends BTreeNode { |
2 | |
3 | public int height; // 树高 |
4 | public int balanceFactor; // 平衡因子 |
5 | |
6 | public AVLNode(int key){ |
7 | super(key); |
8 | } |
9 | } |
AVL树实现类
1 | public class AVLTree extends BTreeSort { |
2 | |
3 | private BTreeNode root; |
4 | |
5 | // 计算树高 |
6 | public int height(BTreeNode root) { |
7 | if (null == root) { |
8 | return 0; |
9 | } |
10 | return ((AVLNode) root).height; |
11 | } |
12 | |
13 | // 计算平衡因子 |
14 | public void UpdateBalanceFactor(BTreeNode root) { |
15 | if (null == root) { |
16 | return; |
17 | } |
18 | int left = height(root.left); |
19 | int right = height(root.right); |
20 | ((AVLNode) root).height = Math.max(left, right) + 1; |
21 | ((AVLNode) root).balanceFactor = left – right; |
22 | } |
23 | |
24 | // 左左类型 — 右转 |
25 | public BTreeNode rotateRight(BTreeNode root) { |
26 | if (null == root) { |
27 | return root; |
28 | } |
29 | BTreeNode node = root.left; |
30 | root.left = node.right; |
31 | node.right = root; |
32 | UpdateBalanceFactor(root); |
33 | UpdateBalanceFactor(node); |
34 | return node; |
35 | } |
36 | |
37 | // 右右类型 — 左转 |
38 | public BTreeNode rotateLeft(BTreeNode root) { |
39 | if (null == root) { |
40 | return root; |
41 | } |
42 | BTreeNode node = root.right; |
43 | root.right = node.left; |
44 | node.left = root; |
45 | UpdateBalanceFactor(root); |
46 | UpdateBalanceFactor(node); |
47 | return node; |
48 | } |
49 | |
50 | // 左右类型 |
51 | public BTreeNode rotateLeftRight(BTreeNode root) { |
52 | if (null == root) { |
53 | return root; |
54 | } |
55 | root.left = rotateLeft(root.left); |
56 | return rotateRight(root); |
57 | } |
58 | |
59 | // 右左类型 |
60 | public BTreeNode rotateRightLeft(BTreeNode root) { |
61 | if (null == root) { |
62 | return root; |
63 | } |
64 | root.right = rotateRight(root.right); |
65 | return rotateLeft(root); |
66 | } |
67 | |
68 | // 插入节点 |
69 | public void insert(int key) { |
70 | if (null == root) { |
71 | root = new AVLNode(key); |
72 | return; |
73 | } |
74 | root = insert(root, key); |
75 | } |
76 | |
77 | // 插入节点构造AVL树 |
78 | public BTreeNode insert(BTreeNode root, int key) { |
79 | if (null == root) { |
80 | root = new AVLNode(key); |
81 | UpdateBalanceFactor(root); |
82 | return root; |
83 | } |
84 | // 等于 |
85 | if (key == root.key) { |
86 | return root; |
87 | } |
88 | // 大于 — 向左 |
89 | if (root.key > key) { |
90 | root.left = insert(root.left, key); |
91 | UpdateBalanceFactor(root); |
92 | // / – 左 |
93 | if (((AVLNode) root).balanceFactor > 1) { |
94 | // / – 左 |
95 | if (((AVLNode) root.left).balanceFactor > 0) { |
96 | root = rotateRight(root); |
97 | } else { |
98 | root = rotateLeftRight(root); |
99 | } |
100 | } |
101 | } |
102 | // 小于或等于 — 向右 |
103 | else { |
104 | root.right = insert(root.right, key); |
105 | UpdateBalanceFactor(root); |
106 | // / – 右 |
107 | if (((AVLNode) root).balanceFactor < –1) { |
108 | // / – 右 |
109 | if (((AVLNode) root.right).balanceFactor < 0) { |
110 | root = rotateLeft(root); |
111 | } else { |
112 | root = rotateRightLeft(root); |
113 | } |
114 | } |
115 | } |
116 | UpdateBalanceFactor(root); |
117 | return root; |
118 | } |
119 | |
120 | // 删除节点 |
121 | public BTreeNode delete(BTreeNode root, int key) { |
122 | if (null == root) { |
123 | return root; |
124 | } |
125 | // 找到需删除的节点 |
126 | if (root.key == key) { |
127 | // 该节点左右子树都不空处理 |
128 | if (null != root.left && null != root.right) { |
129 | // 左边子树高度大于右子树高度,使用左子树中最大节点替换需要删除的节点 |
130 | if (((AVLNode) root.left).height > ((AVLNode) root.right).height) { |
131 | BTreeNode node = max(root.left); |
132 | root.key = node.key; |
133 | root.left = delete(root.left,node.key); |
134 | } else { |
135 | // 使用右子树中最小节点替换需要删除的节点 |
136 | BTreeNode node = min(root.right); |
137 | root.key = node.key; |
138 | root.left = delete(root.right,node.key); |
139 | } |
140 | } else { |
141 | root = null != root.left ? root.left : root.right; |
142 | } |
143 | UpdateBalanceFactor(root); |
144 | return root; |
145 | } |
146 | // 往左边查找删除节点 |
147 | else if (root.key > key) { |
148 | root.left = delete(root.left, key); |
149 | UpdateBalanceFactor(root); |
150 | // 左子树变矮只有可能右子树高度大于等于左子树高度 |
151 | // \ |
152 | if (((AVLNode)root).balanceFactor < –1){ |
153 | // \ 右右类型处理 |
154 | if (((AVLNode)root.left).balanceFactor < 0){ |
155 | root = rotateLeft(root); |
156 | } |
157 | else{ |
158 | // 右左类型处理 |
159 | root = rotateRightLeft(root); |
160 | } |
161 | } |
162 | } |
163 | // 往右边查找删除节点 |
164 | else { |
165 | root.right = delete(root.right, key); |
166 | UpdateBalanceFactor(root); |
167 | // 右子树变矮只有可能左子树高度大于等于右子树高度 |
168 | // / |
169 | if (((AVLNode)root).balanceFactor > 1){ |
170 | // / 左左类型 |
171 | if (((AVLNode)root.left).balanceFactor > 0){ |
172 | root = rotateRight(root); |
173 | } |
174 | else{ |
175 | // 左右类型 |
176 | root = rotateLeftRight(root); |
177 | } |
178 | } |
179 | } |
180 | UpdateBalanceFactor(root); |
181 | return root; |
182 | } |
183 | |
184 | // 中顺遍历 |
185 | public void midTraversal(){ |
186 | this.midTraversal(root); |
187 | } |
188 | |
189 | // 删除节点 |
190 | public void delete(int key) { |
191 | this.delete(root, key); |
192 | } |
193 | |
194 | public static void main(String[] args) { |
195 | Integer[] nums = new Integer[] { 20, 12, 9, 11, 17, 19, 18, 25, 30, 23, |
196 | 55, 35, 67, 81, 13 }; |
197 | System.out.println(Arrays.asList(nums)); |
198 | AVLTree avlTree = new AVLTree(); |
199 | for (Integer num:nums){ |
200 | avlTree.insert(num.intValue()); |
201 | } |
202 | avlTree.delete(20); |
203 | System.out.print(“中序遍历:“); |
204 | avlTree.midTraversal(); |
205 | System.out.println(); |
206 | } |
207 | } |