diff src/tree/AVLTreeMap.java @ 3:24613dfbaeab default tip

finished implementing AVL-Tree remove operation
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Wed, 10 Aug 2011 23:35:57 +0900
parents 36f2373f867b
children
line wrap: on
line diff
--- a/src/tree/AVLTreeMap.java	Wed Aug 10 20:14:19 2011 +0900
+++ b/src/tree/AVLTreeMap.java	Wed Aug 10 23:35:57 2011 +0900
@@ -110,6 +110,7 @@
 			
 			RemoveResult<K,V> r = removeTarget(_cur.right,_key);
 			_cur.right = r.cur;
+			r.cur = _cur;
 			_cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
 			
 			//要素の削除では,部分木の要素が減ったと考えるのではなく,もう片方の部分木の要素が増えたと考えれば書きやすい
@@ -135,6 +136,7 @@
 			
 			RemoveResult<K,V> r = removeTarget(_cur.right,_key);
 			_cur.left = r.cur;
+			r.cur = _cur;
 			_cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
 
 			int diff = _cur.rdepth - _cur.ldepth;
@@ -154,14 +156,34 @@
 		
 		//見つかったので,ノードの代わりのノードを検索する.
 		RemoveResult<K,V> r = findNearestNode(_cur.left);
-		if(r != null){
+		if(r == null){
+			//左部分木は存在していない、そのため右部分木をかわりに配置する
+			r = new RemoveResult<K,V>(_cur,_cur.right);
+		}else{
+			//左部分木より代替ノードを取得した
+			r.removed = new Node<K,V>(_cur.key,_cur.value,0,0,NULL_NODE,NULL_NODE);
+			_cur.key = r.removed.key;
+			_cur.value = r.removed.value;
+			_cur.left = r.cur;
+			r.cur = _cur;
+			
+			_cur.ldepth = Math.max(_cur.left.ldepth,_cur.left.rdepth) + 1;
 			
+			int diff = _cur.rdepth - _cur.ldepth;
+			if(diff > 1){
+				Node<K,V> right = _cur.right;
+				int rottype = right.rdepth - right.ldepth;
+				if(rottype >= 0){
+					r.cur = singleRotate(_cur,OP_RIGHT);
+				}else{
+					r.cur = doubleRotate(_cur,OP_RIGHTLEFT);
+				}
+			}
+			
+			r.removed = _cur;
 		}
 		
-		//見つかった場合は自身を削除対象とする
-		
-		
-		return null;
+		return r;
 	}
 	
 	public RemoveResult<K,V> findNearestNode(Node<K,V> _cur)
@@ -170,7 +192,27 @@
 			return null;
 		}
 		
-		return null;
+		RemoveResult<K,V> r = findNearestNode(_cur.right);
+		if(r == null){
+			r = new RemoveResult<K,V>(_cur,_cur.left);
+			return r;
+		}
+		_cur.right = r.cur;
+		_cur.ldepth = Math.max(_cur.left.ldepth,_cur.left.rdepth) + 1;
+		r.cur = _cur;
+		int diff = _cur.rdepth - _cur.ldepth;
+		
+		if(diff > 1){
+			Node<K,V> left = _cur.left;
+			int rottype = left.ldepth - left.rdepth;
+			if(rottype >= 0){
+				r.cur = singleRotate(_cur,OP_LEFT);
+			}else{
+				r.cur = doubleRotate(_cur,OP_LEFTRIGHT);
+			}
+		}
+		
+		return r;
 	}
 	
 	public static class RemoveResult<K,V>