# 数据结构 - 平衡二叉树

LL：BFnode - BFnode.leftchild - BFnode.leftchild.leftchild （左左）

RR：BFnode - BFnode.rightchild - BFnode.rightchild.rightchild （右右）

LR：BFnode - BFnode.leftchild - BFnode.leftchild.rightchild （左右）

RL：BFnode - BFnode.rightchild - BFnode.rightchild.leftchild （右左）

  1 package collections;
2
3 public class AVLTree {
4
5     private AVLNode root;
6
7     // delete node
8     public void delete(int val) {
9         if (root == null) {
10             return;
11         }
12         AVLNode delNode = get(val);
13         if (delNode == null) {
14             return;
15         }
16         AVLNode replaceNode = findRightLeaf(delNode.leftChild);
17         AVLNode tracebackNode;
18         // delete node self
19         // null means left child is null
20         // contain leaf condition
21         if (replaceNode == null) {
22             AVLNode rightChild = delNode.rightChild;
23             setChild(setParent(rightChild, delNode), delNode, rightChild);
24             tracebackNode = delNode;
25         } else {
26             tracebackNode = replaceDeleteNode(delNode, replaceNode);
27         }
28         // trace back to root
29         tracebackAndConvert(tracebackNode);
30         // clear delete node
31         delNode.parent = null;
32         delNode.leftChild = null;
33         delNode.rightChild = null;
34     }
35
36     // check weather the tree has val
37     public boolean contain(int val) {
38         return get(val) != null;
39     }
40
41     // get node by value
42     public AVLNode get(int val) {
43         if (root == null) {
44             return null;
45         }
46         return get(val, root);
47     }
48
50     public void add(int val) {
51         if (root == null) {
52             root = new AVLNode(val);
53             return;
54         }
55         AVLNode insertNode = new AVLNode(val);
56         AVLNode node = root;
57         while (true) {
58             if (val <= node.val) {
59                 if (node.leftChild == null) {
60                     insertNode.parent = node;
61                     node.leftChild = insertNode;
62                     break;
63                 }
64                 node = node.leftChild;
65             } else {
66                 if (node.rightChild == null) {
67                     insertNode.parent = node;
68                     node.rightChild = insertNode;
69                     break;
70                 }
71                 node = node.rightChild;
72             }
73         }
74         tracebackAndConvert(insertNode);
75     }
76
77     // degree left right print
78     public void showDLR() {
79         iteratorDLR(root);
80     }
81
82     // left degree right print
83     public void showLDR() {
84         iteratorLDR(root);
85     }
86
87     // left right degree print
88     public void showLRD() {
89         iteratorLRD(root);
90     }
91
92     // check empty
93     public boolean isEmpty() {
94         return getDepth(root) == 0;
95     }
96
97     // get tree depth
98     public int depth() {
99         return getDepth(root);
100     }
101
102     // trace back to root and convert structure
103     private void tracebackAndConvert(AVLNode tracebackNode) {
104         while (true) {
105             if (getBF(tracebackNode) == 2) {
106                 // convert structure
107                 convert(tracebackNode);
108             }
109             if (tracebackNode == root) {
110                 break;
111             }
112             tracebackNode = tracebackNode.parent;
113         }
114     }
115
116     // convert structure
117     private void convert(AVLNode convertNode) {
118         StringBuilder sign = new StringBuilder();
119         AVLNode node = getNodeAndRotateType(convertNode, sign);
120         switch (sign.toString()) {
121             case "ll":
122                 rotateLL(convertNode);
123                 break;
124             case "rr":
125                 rotateRR(convertNode);
126                 break;
127             case "lr":
128                 rotateLR(node, convertNode);
129                 break;
130             case "rl":
131                 rotateRL(node, convertNode);
132                 break;
133         }
134     }
135
136     // get node and rotate type
137     private AVLNode getNodeAndRotateType(AVLNode node, StringBuilder sign) {
138         for (int i = 0; i < 2; i++) {
139             // means left child lose balance
140             if (getDepth(node.leftChild) > getDepth(node.rightChild)) {
141                 sign.append('l');
142                 node = node.leftChild;
143             }
144             // means right child lose balance
145             if (getDepth(node.rightChild) > getDepth(node.leftChild)) {
146                 sign.append('r');
147                 node = node.rightChild;
148             }
149         }
150         return node;
151     }
152
153     // replace delete node
154     private AVLNode replaceDeleteNode(AVLNode deleteNode, AVLNode replaceNode) {
155         AVLNode replaceNodeParent = replaceNode.parent;
156         AVLNode replaceNodeLeftChild = replaceNode.leftChild;
157         if (replaceNodeParent.leftChild == replaceNode) {
158             replaceNodeParent.leftChild = replaceNodeLeftChild;
159         } else {
160             replaceNodeParent.rightChild = replaceNodeLeftChild;
161         }
162         if (replaceNodeLeftChild != null) {
163             replaceNodeLeftChild.parent = replaceNodeParent;
164         }
165         AVLNode deleteParent = deleteNode.parent;
166         AVLNode tracebackNode = replaceNode.parent;
167         replaceNode.parent = deleteParent;
168         if (deleteParent.leftChild == deleteNode) {
169             deleteParent.leftChild = replaceNode;
170         } else {
171             deleteParent.rightChild = replaceNode;
172         }
173         // the replace node is the left child of delete node
174         if (deleteNode.leftChild == replaceNode) {
175             replaceNode.leftChild = null;
176         } else {
177             replaceNode.leftChild = deleteNode.leftChild;
178         }
179         replaceNode.rightChild = deleteNode.rightChild;
180         return tracebackNode;
181     }
182
183     // find the right leaf which should replace the removed node
184     private AVLNode findRightLeaf(AVLNode node) {
185         if (node == null) {
186             return null;
187         }
188         if (node.rightChild == null) {
189             return node;
190         }
191         return findRightLeaf(node.rightChild);
192     }
193
194     private AVLNode get(int val, AVLNode node) {
195         if (node == null) {
196             return null;
197         }
198         if (val < node.val) {
199             return get(val, node.leftChild);
200         } else if (val > node.val) {
201             return get(val, node.rightChild);
202         } else {
203             return node;
204         }
205     }
206
207     private void iteratorDLR(AVLNode node) {
208         if (node == null) {
209             return;
210         }
211         System.out.print(node.val + ",");
212         iteratorDLR(node.leftChild);
213         iteratorDLR(node.rightChild);
214     }
215
216     private void iteratorLDR(AVLNode node) {
217         if (node == null) {
218             return;
219         }
220         iteratorLDR(node.leftChild);
221         System.out.print(node.val + ",");
222         iteratorLDR(node.rightChild);
223     }
224
225     private void iteratorLRD(AVLNode node) {
226         if (node == null) {
227             return;
228         }
229         iteratorLRD(node.leftChild);
230         iteratorLRD(node.rightChild);
231         System.out.print(node.val + ",");
232     }
233
234     // ll rotate
235     private void rotateLL(AVLNode convertNode) {
236         AVLNode node = convertNode.leftChild;
237         setChild(setParent(node, convertNode), convertNode, node);
238         convertNode.leftChild = node.rightChild;
239         node.rightChild = convertNode;
240         convertNode.parent = node;
241     }
242
243     // rr rotate
244     private void rotateRR(AVLNode convertNode) {
245         AVLNode node = convertNode.rightChild;
246         setChild(setParent(node, convertNode), convertNode, node);
247         convertNode.rightChild = node.leftChild;
248         node.leftChild = convertNode;
249         convertNode.parent = node;
250     }
251
252     // rl rotate
253     private void rotateRL(AVLNode node, AVLNode convertNode) {
254         setChild(setParent(node, convertNode), convertNode, node);
255         AVLNode rightChild = convertNode.rightChild;
256         rightChild.parent = node;
257         rightChild.leftChild = null;
258         node.leftChild = convertNode;
259         node.rightChild = rightChild;
260         convertNode.parent = node;
261         convertNode.rightChild = null;
262     }
263
264     // lr rotate
265     private void rotateLR(AVLNode node, AVLNode convertNode) {
266         setChild(setParent(node, convertNode), convertNode, node);
267         AVLNode leftChild = convertNode.leftChild;
268         leftChild.parent = node;
269         leftChild.rightChild = null;
270         node.leftChild = leftChild;
271         node.rightChild = convertNode;
272         convertNode.parent = node;
273         convertNode.leftChild = null;
274     }
275
276     private AVLNode setParent(AVLNode node, AVLNode convertNode) {
277         AVLNode parent = convertNode.parent;
278         if (node != null) {
279             node.parent = parent;
280         }
281         return parent;
282     }
283
284     private void setChild(AVLNode parent, AVLNode originChild, AVLNode newChild) {
285         if (parent == null) {
286             root = newChild;
287             return;
288         }
289         if (parent.leftChild == originChild) {
290             parent.leftChild = newChild;
291         } else {
292             parent.rightChild = newChild;
293         }
294     }
295
296     // get balance fate
297     private int getBF(AVLNode node) {
298         if (node == null) {
299             return 0;
300         }
301         return Math.abs(getDepth(node.leftChild) - getDepth(node.rightChild));
302     }
303
304     // get node depth
305     private int getDepth(AVLNode node) {
306         if (node == null) {
307             return 0;
308         }
309         return 1 + Math.max(getDepth(node.leftChild), getDepth(node.rightChild));
310     }
311
312     public static void main(String[] args) {
313         AVLTree tree = new AVLTree();
321         tree.showDLR();
322         System.out.println();
323         tree.delete(47);
324         tree.showDLR();
325         System.out.println();
327         tree.showDLR();
328     }
329
330 }
331
332 class AVLNode {
333     AVLNode parent;
334     AVLNode leftChild;
335     AVLNode rightChild;
336     int val;
337
338     public AVLNode(AVLNode parent, AVLNode leftChild, AVLNode rightChild, int val) {
339         this.parent = parent;
340         this.leftChild = leftChild;
341         this.rightChild = rightChild;
342         this.val = val;
343     }
344
345     public AVLNode(int val) {
346         this.parent = null;
347         this.leftChild = null;
348         this.rightChild = null;
349         this.val = val;
350     }
351
352 }

posted @ 2020-05-28 17:43  SamNicole1809  阅读(16)  评论(0编辑  收藏