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