@@ -33,6 +33,44 @@ public boolean isEmpty() {
3333 return size == 0 ;
3434 }
3535
36+ // 判断该二叉树是否是一棵二分搜索树
37+ public boolean isBST () {
38+ ArrayList <K > keys = new ArrayList <>();
39+ inOrder (root , keys );
40+ for (int i = 1 ; i < keys .size (); i ++) {
41+ if (keys .get (i - 1 ).compareTo (keys .get (i )) > 0 ) {
42+ return false ;
43+ }
44+ }
45+ return true ;
46+ }
47+
48+ private void inOrder (Node node , ArrayList <K > keys ) {
49+ if (node == null ) {
50+ return ;
51+ }
52+ inOrder (node .left , keys );
53+ keys .add (node .key );
54+ inOrder (node .right , keys );
55+ }
56+
57+ // 判断该二叉树是否是一棵平衡二叉树
58+ public boolean isBalanced () {
59+ return isBalanced (root );
60+ }
61+
62+ // 判断以Node节点为根的二叉树是否是一棵平衡二叉树,递归算法
63+ private boolean isBalanced (Node node ) {
64+ if (node == null ) {
65+ return true ;
66+ }
67+ int balanceFactor = getBalanceFactor (node );
68+ if (Math .abs (balanceFactor ) > 1 ) {
69+ return false ;
70+ }
71+ return isBalanced (node .left ) && isBalanced (node .right );
72+ }
73+
3674 private int getHeight (Node node ) {
3775 if (node == null )
3876 return 0 ;
@@ -47,6 +85,38 @@ private int getBalanceFactor(Node node) {
4785 return getHeight (node .left ) - getHeight (node .right );
4886 }
4987
88+ // 对节点y进行向右旋转操作,返回旋转后新的根节点x
89+ private Node rightRotate (Node y ) {
90+ Node x = y .left ;
91+ Node T3 = x .right ;
92+
93+ // 向右旋转过程
94+ x .right = y ;
95+ y .left = T3 ;
96+
97+ // 更新 height (只需要更新 y和x, 先y后x)
98+ y .height = Math .max (getHeight (y .left ), getHeight (y .right )) + 1 ;
99+ x .height = Math .max (getHeight (x .left ), getHeight (x .right )) + 1 ;
100+
101+ return x ;
102+ }
103+
104+ // 对节点y进行向左旋转操作,返回旋转后新的根节点x
105+ private Node leftRotate (Node y ) {
106+ Node x = y .right ;
107+ Node T2 = x .left ;
108+
109+ // 向左旋转过程
110+ x .left = y ;
111+ y .right = T2 ;
112+
113+ // 更新 height (只需要更新 y和x, 先y后x)
114+ y .height = Math .max (getHeight (y .left ), getHeight (y .right )) + 1 ;
115+ x .height = Math .max (getHeight (x .left ), getHeight (x .right )) + 1 ;
116+
117+ return x ;
118+ }
119+
50120 // 向二分搜索树中添加新的元素(key, value)
51121 public void add (K key , V value ) {
52122 root = add (root , key , value );
@@ -73,8 +143,28 @@ else if (key.compareTo(node.key) > 0)
73143
74144 // 计算平衡因子
75145 int balanceFactor = getBalanceFactor (node );
76- if (Math .abs (balanceFactor ) > 1 ) {
77- System .out .println ("unbabalanced : " + balanceFactor );
146+ // if (Math.abs(balanceFactor) > 1) {
147+ // System.out.println("unbabalanced : " + balanceFactor);
148+ // }
149+
150+ // 平衡维护
151+ // LL
152+ if (balanceFactor > 1 && getBalanceFactor (node .left ) >= 0 ) {
153+ return rightRotate (node );
154+ }
155+ // RR
156+ if (balanceFactor < -1 && getBalanceFactor (node .right ) <= 0 ) {
157+ return leftRotate (node );
158+ }
159+ // LR
160+ if (balanceFactor > 1 && getBalanceFactor (node .left ) < 0 ) {
161+ node .left = leftRotate (node .left ); // 转化成LL
162+ return rightRotate (node );
163+ }
164+ // RL
165+ if (balanceFactor < -1 && getBalanceFactor (node .right ) > 0 ) {
166+ node .right = rightRotate (node .right );// 转化成RR
167+ return leftRotate (node );
78168 }
79169
80170 return node ;
@@ -150,50 +240,85 @@ private Node remove(Node node, K key) {
150240 if (node == null )
151241 return null ;
152242
243+ Node retNode ;
153244 if (key .compareTo (node .key ) < 0 ) {
154245 node .left = remove (node .left , key );
155- return node ;
246+ retNode = node ;
156247 } else if (key .compareTo (node .key ) > 0 ) {
157248 node .right = remove (node .right , key );
158- return node ;
249+ retNode = node ;
159250 } else { // key.compareTo(node.key) == 0
160251
161252 // 待删除节点左子树为空的情况
162253 if (node .left == null ) {
163254 Node rightNode = node .right ;
164255 node .right = null ;
165256 size --;
166- return rightNode ;
257+ retNode = rightNode ;
167258 }
168259
169260 // 待删除节点右子树为空的情况
170- if (node .right == null ) {
261+ else if (node .right == null ) {
171262 Node leftNode = node .left ;
172263 node .left = null ;
173264 size --;
174- return leftNode ;
175- }
265+ retNode = leftNode ;
266+ } else { // 待删除节点左右子树均不为空的情况
176267
177- // 待删除节点左右子树均不为空的情况
268+ // 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
269+ // 用这个节点顶替待删除节点的位置
270+ Node successor = minimum (node .right );
271+ // successor.right = removeMin(node.right); // 注意平衡
272+ successor .right = remove (node .right , successor .key ); // 注意平衡
273+ successor .left = node .left ;
274+
275+ node .left = node .right = null ;
276+
277+ retNode = successor ;
278+ }
178279
179- // 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
180- // 用这个节点顶替待删除节点的位置
181- Node successor = minimum (node .right );
182- successor .right = removeMin (node .right );
183- successor .left = node .left ;
280+ }
281+ if (retNode == null ) // 注意空处理
282+ return null ;
184283
185- node .left = node .right = null ;
284+ // 更新 height
285+ retNode .height = 1 + Math .max (getHeight (retNode .left ), getHeight (retNode .right ));
186286
187- return successor ;
287+ // 计算平衡因子
288+ int balanceFactor = getBalanceFactor (retNode );
289+ // if (Math.abs(balanceFactor) > 1) {
290+ // System.out.println("unbabalanced : " + balanceFactor);
291+ // }
292+
293+ // 平衡维护
294+ // LL
295+ if (balanceFactor > 1 && getBalanceFactor (retNode .left ) >= 0 ) {
296+ return rightRotate (retNode );
297+ }
298+ // RR
299+ if (balanceFactor < -1 && getBalanceFactor (retNode .right ) <= 0 ) {
300+ return leftRotate (retNode );
301+ }
302+ // LR
303+ if (balanceFactor > 1 && getBalanceFactor (retNode .left ) < 0 ) {
304+ retNode .left = leftRotate (retNode .left ); // 转化成LL
305+ return rightRotate (retNode );
188306 }
307+ // RL
308+ if (balanceFactor < -1 && getBalanceFactor (retNode .right ) > 0 ) {
309+ retNode .right = rightRotate (retNode .right );// 转化成RR
310+ return leftRotate (retNode );
311+ }
312+
313+ return retNode ;
189314 }
190315
191316 public static void main (String [] args ) {
192317
193318 System .out .println ("Pride and Prejudice" );
194319
195320 ArrayList <String > words = new ArrayList <>();
196- if (FileOperation .readFile ("pride-and-prejudice.txt" , words )) {
321+ if (FileOperation .readFile ("AVLTree/ pride-and-prejudice.txt" , words )) {
197322 System .out .println ("Total words: " + words .size ());
198323
199324 AVLTree <String , Integer > map = new AVLTree <>();
@@ -207,6 +332,15 @@ public static void main(String[] args) {
207332 System .out .println ("Total different words: " + map .getSize ());
208333 System .out .println ("Frequency of PRIDE: " + map .get ("pride" ));
209334 System .out .println ("Frequency of PREJUDICE: " + map .get ("prejudice" ));
335+
336+ System .out .println ("is BST : " + map .isBST ());
337+ System .out .println ("is isBalanced : " + map .isBalanced ());
338+
339+ for (String word : words ) {
340+ map .remove (word );
341+ if (!map .isBST () || !map .isBalanced ())
342+ throw new RuntimeException ("Error" );
343+ }
210344 }
211345
212346 System .out .println ();
0 commit comments