Skip to content

Commit 18c7f83

Browse files
committed
AVL树的创建(左旋和右旋)
1 parent b1f3a46 commit 18c7f83

File tree

2 files changed

+254
-2
lines changed

2 files changed

+254
-2
lines changed

app/src/main/java/com/liuxiaozhu/binarytree/AVLTree.java

Lines changed: 238 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,243 @@
66
* 创建AVL树(平衡二叉树)
77
*/
88

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;
1021

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+
}
11248
}

app/src/main/java/com/liuxiaozhu/binarytree/MainActivity.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import android.util.Log;
66

77
import java.util.ArrayList;
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.Executors;
810

911
/**
1012
* 二叉树的遍历
@@ -21,8 +23,21 @@ protected void onCreate(Bundle savedInstanceState) {
2123
// 测试二叉排序树
2224
// testSearchBinaryTree();
2325
// 测试haffMan树
24-
testHaffManTree();
26+
// testHaffManTree();
27+
//测试AVL(平衡二叉树)
28+
// testAVLTree();
29+
}
2530

31+
/**
32+
* 测试AVL(平衡二叉树)
33+
*/
34+
private void testAVLTree() {
35+
Integer[] nums = {5, 8, 2, 0, 1, -2};
36+
AVLTree<Integer> tree = new AVLTree<>();
37+
for (int i = 0; i < nums.length; i++) {
38+
tree.insertElement(nums[i]);
39+
}
40+
Log.e("AVL", "" + tree.root.element);
2641
}
2742

2843
/**

0 commit comments

Comments
 (0)