comparison src/tree/AVLTreeMap.java @ 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
comparison
equal deleted inserted replaced
1:15920e9b562d 2:36f2373f867b
9 { 9 {
10 AVLTreeMap<Integer,String> map = new AVLTreeMap<Integer,String>(); 10 AVLTreeMap<Integer,String> map = new AVLTreeMap<Integer,String>();
11 11
12 map.put(10,"10"); 12 map.put(10,"10");
13 map.put(20,"20"); 13 map.put(20,"20");
14 map.put(30,"20"); 14 map.put(30,"30");
15 map.put(5,"5"); 15 map.put(5,"5");
16 map.put(7,"7"); 16 map.put(7,"7");
17
18 map.remove(20);
17 } 19 }
18 20
19 public AVLTreeMap() 21 public AVLTreeMap()
20 { 22 {
21 root = null; 23 root = null;
86 } 88 }
87 89
88 return cur; 90 return cur;
89 } 91 }
90 92
91 public V remove(K key) 93 public V remove(K _key)
92 { 94 {
93 RemoveResult<K,V> r = findRemoveTarget(root,key); 95 RemoveResult<K,V> r = removeTarget(root,_key);
94 root = r.cur; 96 root = r.cur;
95 return r.target.value; 97 return r.removed.value;
96 } 98 }
97 99
98 private RemoveResult<K,V> findRemoveTarget(Node<K,V> cur,K key) 100 private RemoveResult<K,V> removeTarget(Node<K,V> _cur,K _key)
99 { 101 {
100 int result = cur.key.compareTo(key); 102 int result = _cur.key.compareTo(_key);
103
101 if(result < 0){ 104 if(result < 0){
102 //right 105 //right
103 if(cur == NULL_NODE){ 106 if(_cur.right == NULL_NODE){
104 return new RemoveResult<K,V>(cur,NULL_NODE); 107 //not found
105 } 108 return new RemoveResult<K,V>(_cur,NULL_NODE);
106 109 }
107 RemoveResult<K,V> r = findRemoveTarget(cur.right,key); 110
108 cur.right = r.cur; 111 RemoveResult<K,V> r = removeTarget(_cur.right,_key);
109 cur.rdepth = Math.max(cur.right.rdepth,cur.right.ldepth) + 1; 112 _cur.right = r.cur;
110 113 _cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
111 int diff = cur.rdepth - cur.ldepth; 114
112 if(diff > 1){ 115 //要素の削除では,部分木の要素が減ったと考えるのではなく,もう片方の部分木の要素が増えたと考えれば書きやすい
113 int rottype = result * cur.right.key.compareTo(key); 116 int diff = _cur.ldepth - _cur.rdepth;
114 if(rottype > 0){ 117 if(diff > 1){
115 r.cur = singleRotate(cur,OP_RIGHT); 118 //determine that rotation will be single or double
116 return r; 119 Node<K,V> left = _cur.left;
117 }else{ 120 int rottype = left.ldepth - left.rdepth;
118 r.cur = doubleRotate(cur,OP_RIGHTLEFT); 121 if(rottype >= 0){
119 return r; 122 r.cur = singleRotate(_cur,OP_LEFT);
120 } 123 }else{
121 } 124 r.cur = doubleRotate(_cur,OP_LEFTRIGHT);
122 125 }
123 r.cur = cur; 126 }
127
124 return r; 128 return r;
125 }else if(result > 0 ){ 129 }else if(result > 0){
126 //left 130 //left
127 if(cur == NULL_NODE){ 131 if(_cur.left == NULL_NODE){
128 return new RemoveResult<K,V>(cur,NULL_NODE); 132 //not found
129 } 133 return new RemoveResult<K,V>(_cur,NULL_NODE);
130 134 }
131 RemoveResult<K,V> r = findRemoveTarget(cur.left,key); 135
132 cur.left = r.cur; 136 RemoveResult<K,V> r = removeTarget(_cur.right,_key);
133 cur.ldepth = Math.max(cur.left.rdepth,cur.left.ldepth) + 1; 137 _cur.left = r.cur;
134 138 _cur.rdepth = Math.max(_cur.right.ldepth,_cur.right.rdepth) + 1;
135 int diff = cur.rdepth - cur.ldepth; 139
136 if(diff > 1){ 140 int diff = _cur.rdepth - _cur.ldepth;
137 int rottype = result * cur.left.key.compareTo(key); 141 if(diff > 1){
138 if(rottype > 0){ 142 //determine that rotation will be single or double
139 r.cur = singleRotate(cur,OP_LEFT); 143 Node<K,V> right = _cur.right;
140 return r; 144 int rottype = right.rdepth - right.ldepth;
141 }else{ 145 if(rottype >= 0){
142 r.cur = doubleRotate(cur,OP_LEFTRIGHT); 146 r.cur = singleRotate(_cur,OP_RIGHT);
143 return r; 147 }else{
144 } 148 r.cur = doubleRotate(_cur,OP_RIGHTLEFT);
145 } 149 }
146 150 }
147 r.cur = cur; 151 }
148 return r; 152
149 }else{ 153 //find.
150 //find 154
151 if(cur.left == NULL_NODE && cur.right == NULL_NODE){ 155 //見つかったので,ノードの代わりのノードを検索する.
152 //delete 156 RemoveResult<K,V> r = findNearestNode(_cur.left);
153 return new RemoveResult<K,V>(NULL_NODE,cur); 157 if(r != null){
154 } 158
155 159 }
156 if(cur.left != NULL_NODE && cur.right == NULL_NODE){ 160
157 //replace left 161 //見つかった場合は自身を削除対象とする
158 return new RemoveResult<K,V>(cur.left,cur); 162
159 } 163
160 164 return null;
161 if(cur.left == NULL_NODE && cur.right != NULL_NODE){ 165 }
162 //replace right 166
163 return new RemoveResult<K,V>(cur.right,cur); 167 public RemoveResult<K,V> findNearestNode(Node<K,V> _cur)
164 } 168 {
165 169 if(_cur == NULL_NODE){
166 //both nodes are not null 170 return null;
167 RemoveResult<K,V> r = findSubstituteNode(cur.left); 171 }
168 cur.key = r.target.key; 172
169 cur.value = r.target.value; 173 return null;
170 cur.right = r.cur; 174 }
171 cur.rdepth = Math.max(cur.ldepth,cur.rdepth) + 1; 175
172 176 public static class RemoveResult<K,V>
173 int diff = cur.rdepth - cur.ldepth; 177 {
174 if(diff > 1){ 178 public Node<K,V> removed;
175 r.cur = doubleRotate(cur,OP_LEFTRIGHT); 179 public Node<K,V> cur;
176 } 180
177 181 public RemoveResult(Node<K,V> _removed,Node<K,V> _cur)
178 return r;
179 }
180 }
181
182 private RemoveResult<K,V> findSubstituteNode(Node<K,V> cur)
183 {
184 if(cur.right != NULL_NODE){
185 RemoveResult<K,V> result = findSubstituteNode(cur.right);
186 cur.right = result.cur;
187 cur.rdepth = Math.max(cur.right.rdepth,cur.right.ldepth) + 1;
188
189 int diff = cur.ldepth - cur.rdepth;
190 if(diff > 1){
191 result.cur = singleRotate(cur.left,OP_LEFT);
192 return result;
193 }
194
195 result.cur = cur;
196 return result;
197 }
198
199 RemoveResult<K,V> result = new RemoveResult<K,V>(cur.left,cur);
200 return result;
201 }
202
203 private static class RemoveResult<K,V>
204 {
205 Node<K,V> cur;
206 Node<K,V> target;
207
208 public RemoveResult(Node<K,V> cur,Node<K,V> target)
209 { 182 {
210 this.cur = cur; 183 removed = _removed;
211 this.target = target; 184 cur = _cur;
212 } 185 }
213 } 186 }
214 187
215 private static final int OP_LEFT = 1; 188 private static final int OP_LEFT = 1;
216 private static final int OP_RIGHT = 2; 189 private static final int OP_RIGHT = 2;