001/* 002 File: RBTree.java 003 004 Originally written by Doug Lea and released into the public domain. 005 Thanks for the assistance and support of Sun Microsystems Labs, Agorics 006 Inc, Loral, and everyone contributing, testing, and using this code. 007 008 History: 009 Date Who What 010 24Sep95 dl@cs.oswego.edu Create from collections.java working file 011 13Oct95 dl Changed protection statuses 012 013*/ 014 015package cnslab.cnsmath; 016import cnslab.cnsnetwork.*; 017import java.util.Map; 018import java.io.PrintStream; 019 020/** 021 * 022 * RedBlack trees. 023 * @author Doug Lea 024 * @version 0.93 025 * 026 * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>. 027**/ 028public class RBTree<T extends Comparable > 029{ 030 031 // instance variables 032 033 /** 034 * The root of the tree. Null if empty. 035 * 036 **/ 037 /** 038 * Returns the root of the tree. 039 * 040 * @return The root of the tree. 041 */ 042 043 public RBCell<T> root() 044 { 045 return this.root; 046 } 047 048 private RBCell<T> root; 049 050 protected int count_; 051 052 /** 053 *make iterate exit 054 */ 055 public boolean iterExit; 056 057 /** 058 * save time for noTillInputEvent iteration 059 */ 060 public FireEvent firstFire; 061 062 /** 063 * save time for noTillFireEvent iteration 064 */ 065 public InputEvent firstInput; 066 067 public Map flags; 068 069 070 protected final void incCount() { count_++; } 071 protected final void decCount() { count_--; } 072 073 // constructors 074 /** 075 * Constructs a new empty tree. 076 */ 077 public RBTree() 078 { 079 root = null; 080 } 081 082 /** 083 * Constructs a new tree with a root node x. 084 * 085 * @param x The root node of the tree. 086 */ 087 public RBTree(RBCell<T> x) 088 { 089 root = x; 090 } 091 092 093/** 094 * set the element count and update version_ if changed 095**/ 096 protected final void setCount(int c) { 097 if (c != count_) { count_ = c; } 098 } 099 100 101 102// Collection methods 103 104/** 105 * Implements collections.Collection.includes. 106 * Time complexity: O(log n). 107 * @see collections.Collection#includes 108**/ 109 public synchronized boolean includes(T element) { 110 if (element == null || count_ == 0) return false; 111 return root.find(element) != null; 112 } 113 114/** 115 * Implements collections.Collection.occurrencesOf. 116 * Time complexity: O(log n). 117 * @see collections.Collection#occurrencesOf 118**/ 119 public synchronized int occurrencesOf(T element) { 120 if (element == null || count_ == 0) return 0; 121 return root.count(element); 122 } 123 124 125// UpdatableCollection methods 126 127/** 128 * Implements collections.UpdatableCollection.clear. 129 * Time complexity: O(1). 130 * @see collections.UpdatableCollection#clear 131**/ 132 public synchronized void clear() { 133 setCount(0); 134 root = null; 135 } 136 137/** 138 * Implements collections.UpdatableCollection.exclude. 139 * Time complexity: O(log n * occurrencesOf(element)). 140 * @see collections.UpdatableCollection#exclude 141**/ 142 public synchronized void exclude(T element) { 143 remove_(element, true); 144 } 145 146 147/** 148 * Implements collections.UpdatableCollection.removeOneOf. 149 * Time complexity: O(log n). 150 * @see collections.UpdatableCollection#removeOneOf 151**/ 152 public synchronized void removeOneOf(T element) { 153 remove_(element, false); 154 } 155 156/** 157 * Implements collections.UpdatableCollection.replaceOneOf 158 * Time complexity: O(log n). 159 * @see collections.UpdatableCollection#replaceOneOf 160**/ 161 public synchronized void replaceOneOf(T oldElement, T newElement) { 162 replace_(oldElement, newElement, false); 163 } 164 165/** 166 * Implements collections.UpdatableCollection.replaceAllOf. 167 * Time complexity: O(log n * occurrencesOf(oldElement)). 168 * @see collections.UpdatableCollection#replaceAllOf 169**/ 170 public synchronized void replaceAllOf(T oldElement, T newElement) { 171 replace_(oldElement, newElement, true); 172 } 173 174/** 175 * Implements collections.UpdatableCollection.take. 176 * Time complexity: O(log n). 177 * Takes the least element. 178 * @see collections.UpdatableCollection#take 179**/ 180 public synchronized T take() { 181 if (count_ != 0) { 182 RBCell<T> p = root.leftmost(); 183 T v = p.element(); 184 root = p.delete(root); 185 decCount(); 186 return v; 187 } 188 return null; // not reached 189 } 190 191 192// UpdatableBag methods 193 194/** 195 * Implements collections.UpdatableBag.addIfAbsent 196 * Time complexity: O(log n). 197 * @see collections.UpdatableBag#addIfAbsent 198**/ 199 public synchronized void addIfAbsent(T element) { 200 add_(element, true); 201 } 202 203 204/** 205 * Implements collections.UpdatableBag.add. 206 * Time complexity: O(log n). 207 * @see collections.UpdatableBag#add 208**/ 209 public synchronized void add(T element) { 210 add_(element, false); 211 } 212 213 214// helper methods 215 216 private void add_(T element, boolean checkOccurrence) { 217 if (root == null) { 218 root = new RBCell<T>(element); 219 incCount(); 220 } 221 else { 222 RBCell<T> t = root; 223 for (;;) { 224 int diff = element.compareTo(t.element()); 225 if (diff == 0 && checkOccurrence) return; 226 else if (diff <= 0) { 227 if (t.left() != null) 228 t = t.left(); 229 else { 230 root = t.insertLeft(new RBCell<T>(element), root); 231 incCount(); 232 return; 233 } 234 } 235 else { 236 if (t.right() != null) 237 t = t.right(); 238 else { 239 root = t.insertRight(new RBCell<T>(element), root); 240 incCount(); 241 return; 242 } 243 } 244 } 245 } 246 } 247 248 249 private void remove_(T element, boolean allOccurrences) { 250 if (element == null) return; 251 while (count_ > 0) { 252 RBCell<T> p = root.find(element); 253 if (p != null) { 254 root = p.delete(root); 255 decCount(); 256 if (!allOccurrences) return; 257 } 258 else 259 { 260// throw new RuntimeException(" delete null"); 261 break; 262 } 263 } 264 } 265 266 private void replace_(T oldElement, T newElement, boolean allOccurrences) { 267 if (oldElement == null || count_ == 0 || oldElement.equals(newElement)) 268 return; 269 while (includes(oldElement)) { 270 removeOneOf(oldElement); 271 add(newElement); 272 if (!allOccurrences) return; 273 } 274 } 275 276// ImplementationCheckable methods 277// 278 279 public boolean treeNoTillFireEvent(RBCell<T> x) 280 { 281 return true; 282 } 283 284 public boolean treeNoTillFireEvent2(RBCell<T> x) 285 { 286 return true; 287 } 288 289 public boolean treeNoTillInputEvent(RBCell<T> x) 290 { 291 return true; 292 } 293 294 /** 295 * Prints the keys of current tree in inorder (ascending). 296 * Runs in Theta(n) time. 297 * 298 * @param x The node from which to start. 299 */ 300 public void inorderTreeWalk(RBCell<T> x, PrintStream p) 301 { 302 if (!(x==null)) 303 { 304 inorderTreeWalk(x.left(), p); 305 //System.out.println(x.key()); 306 p.println(x.element_); 307 inorderTreeWalk(x.right(), p); 308 } 309 310 } 311 312 public void inorderTreeWalk(RBCell<T> x, StringWrap p) 313 { 314 if (!(x==null)) 315 { 316 inorderTreeWalk(x.left(),p); 317 //System.out.println(x.key()); 318 p.out=p.out+x.element_+" | "; 319 inorderTreeWalk(x.right(),p); 320 } 321 } 322 323} 324