changeset 2:36f2373f867b

added AVLTree.java remove operation
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Wed, 10 Aug 2011 20:14:19 +0900
parents 15920e9b562d
children 24613dfbaeab
files src/tree/AVLTreeMap.java
diffstat 1 files changed, 66 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/src/tree/AVLTreeMap.java	Tue Aug 09 11:13:36 2011 +0900
+++ b/src/tree/AVLTreeMap.java	Wed Aug 10 20:14:19 2011 +0900
@@ -11,9 +11,11 @@
 		
 		map.put(10,"10");
 		map.put(20,"20");
-		map.put(30,"20");
+		map.put(30,"30");
 		map.put(5,"5");
 		map.put(7,"7");
+		
+		map.remove(20);
 	}
 	
 	public AVLTreeMap()
@@ -88,127 +90,98 @@
 		return cur;
 	}
 	
-	public V remove(K key)
+	public V remove(K _key)
 	{
-		RemoveResult<K,V> r = findRemoveTarget(root,key);
+		RemoveResult<K,V> r = removeTarget(root,_key);
 		root = r.cur;
-		return r.target.value;
+		return r.removed.value;
 	}
 	
-	private RemoveResult<K,V> findRemoveTarget(Node<K,V> cur,K key)
+	private RemoveResult<K,V> removeTarget(Node<K,V> _cur,K _key)
 	{
-		int result = cur.key.compareTo(key);
+		int result = _cur.key.compareTo(_key);
+		
 		if(result < 0){
 			//right
-			if(cur == NULL_NODE){
-				return new RemoveResult<K,V>(cur,NULL_NODE);
+			if(_cur.right == NULL_NODE){
+				//not found
+				return new RemoveResult<K,V>(_cur,NULL_NODE);
 			}
 			
-			RemoveResult<K,V> r = findRemoveTarget(cur.right,key);
-			cur.right = r.cur;
-			cur.rdepth = Math.max(cur.right.rdepth,cur.right.ldepth) + 1;
-			
-			int diff = cur.rdepth - cur.ldepth;
-			if(diff > 1){
-				int rottype = result * cur.right.key.compareTo(key);
-				if(rottype > 0){
-					r.cur = singleRotate(cur,OP_RIGHT);
-					return r;
-				}else{
-					r.cur = doubleRotate(cur,OP_RIGHTLEFT);
-					return r;
-				}
-			}
+			RemoveResult<K,V> r = removeTarget(_cur.right,_key);
+			_cur.right = r.cur;
+			_cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
 			
-			r.cur = cur;
-			return r;
-		}else if(result > 0 ){
-			//left
-			if(cur == NULL_NODE){
-				return new RemoveResult<K,V>(cur,NULL_NODE);
-			}
-			
-			RemoveResult<K,V> r = findRemoveTarget(cur.left,key);
-			cur.left = r.cur;
-			cur.ldepth = Math.max(cur.left.rdepth,cur.left.ldepth) + 1;
-			
-			int diff = cur.rdepth - cur.ldepth;
+			//要素の削除では,部分木の要素が減ったと考えるのではなく,もう片方の部分木の要素が増えたと考えれば書きやすい
+			int diff = _cur.ldepth - _cur.rdepth;
 			if(diff > 1){
-				int rottype = result * cur.left.key.compareTo(key);
-				if(rottype > 0){
-					r.cur = singleRotate(cur,OP_LEFT);
-					return r;
+				//determine that rotation will be single or double
+				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;
+					r.cur = doubleRotate(_cur,OP_LEFTRIGHT);
 				}
 			}
 			
-			r.cur = cur;
 			return r;
-		}else{
-			//find
-			if(cur.left == NULL_NODE && cur.right == NULL_NODE){
-				//delete
-				return new RemoveResult<K,V>(NULL_NODE,cur);
-			}
-			
-			if(cur.left != NULL_NODE && cur.right == NULL_NODE){
-				//replace left
-				return new RemoveResult<K,V>(cur.left,cur);
-			}
-			
-			if(cur.left == NULL_NODE && cur.right != NULL_NODE){
-				//replace right
-				return new RemoveResult<K,V>(cur.right,cur);
-			}
-			
-			//both nodes are not null
-			RemoveResult<K,V> r = findSubstituteNode(cur.left);
-			cur.key = r.target.key;
-			cur.value = r.target.value;
-			cur.right = r.cur;
-			cur.rdepth = Math.max(cur.ldepth,cur.rdepth) + 1;
-			
-			int diff = cur.rdepth - cur.ldepth;
-			if(diff > 1){
-				r.cur = doubleRotate(cur,OP_LEFTRIGHT);
+		}else if(result > 0){
+			//left
+			if(_cur.left == NULL_NODE){
+				//not found
+				return new RemoveResult<K,V>(_cur,NULL_NODE);
 			}
 			
-			return r;
+			RemoveResult<K,V> r = removeTarget(_cur.right,_key);
+			_cur.left = r.cur;
+			_cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
+
+			int diff = _cur.rdepth - _cur.ldepth;
+			if(diff > 1){
+				//determine that rotation will be single or double
+				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);
+				}
+			}
 		}
+		
+		//find.
+		
+		//見つかったので,ノードの代わりのノードを検索する.
+		RemoveResult<K,V> r = findNearestNode(_cur.left);
+		if(r != null){
+			
+		}
+		
+		//見つかった場合は自身を削除対象とする
+		
+		
+		return null;
 	}
 	
-	private RemoveResult<K,V> findSubstituteNode(Node<K,V> cur)
+	public RemoveResult<K,V> findNearestNode(Node<K,V> _cur)
 	{
-		if(cur.right != NULL_NODE){
-			RemoveResult<K,V> result = findSubstituteNode(cur.right);
-			cur.right = result.cur;
-			cur.rdepth = Math.max(cur.right.rdepth,cur.right.ldepth) + 1;
-			
-			int diff = cur.ldepth - cur.rdepth;
-			if(diff > 1){
-				result.cur = singleRotate(cur.left,OP_LEFT);
-				return result;
-			}
-			
-			result.cur = cur;
-			return result;
+		if(_cur == NULL_NODE){
+			return null;
 		}
 		
-		RemoveResult<K,V> result = new RemoveResult<K,V>(cur.left,cur);
-		return result;
+		return null;
 	}
 	
-	private static class RemoveResult<K,V>
+	public static class RemoveResult<K,V>
 	{
-		Node<K,V> cur;
-		Node<K,V> target;
+		public Node<K,V> removed;
+		public Node<K,V> cur;
 		
-		public RemoveResult(Node<K,V> cur,Node<K,V> target)
+		public RemoveResult(Node<K,V> _removed,Node<K,V> _cur)
 		{
-			this.cur = cur;
-			this.target = target;
+			removed = _removed;
+			cur = _cur;
 		}
 	}