/**
  * Returns a deep copy of this tree set.
  *
  * <p>This method performs a deep copy of this tree set; the data stored in the set, however, is
  * not cloned. Note that this makes a difference only for object keys.
  *
  * @return a deep copy of this tree set.
  */
 @SuppressWarnings("unchecked")
 public Object clone() {
   ObjectRBTreeSet<K> c;
   try {
     c = (ObjectRBTreeSet<K>) super.clone();
   } catch (CloneNotSupportedException cantHappen) {
     throw new InternalError();
   }
   c.allocatePaths();
   if (count != 0) {
     // Also this apparently unfathomable code is derived from GNU libavl.
     Entry<K> e, p, q, rp = new Entry<K>(), rq = new Entry<K>();
     p = rp;
     rp.left(tree);
     q = rq;
     rq.pred(null);
     while (true) {
       if (!p.pred()) {
         e = p.left.clone();
         e.pred(q.left);
         e.succ(q);
         q.left(e);
         p = p.left;
         q = q.left;
       } else {
         while (p.succ()) {
           p = p.right;
           if (p == null) {
             q.right = null;
             c.tree = rq.left;
             c.firstEntry = c.tree;
             while (c.firstEntry.left != null) c.firstEntry = c.firstEntry.left;
             c.lastEntry = c.tree;
             while (c.lastEntry.right != null) c.lastEntry = c.lastEntry.right;
             return c;
           }
           q = q.right;
         }
         p = p.right;
         q = q.right;
       }
       if (!p.succ()) {
         e = p.right.clone();
         e.succ(q.right);
         e.pred(q);
         q.right(e);
       }
     }
   }
   return c;
 }
 /**
  * Reads the given number of entries from the input stream, returning the corresponding tree.
  *
  * @param s the input stream.
  * @param n the (positive) number of entries to read.
  * @param pred the entry containing the key that preceeds the first key in the tree.
  * @param succ the entry containing the key that follows the last key in the tree.
  */
 @SuppressWarnings("unchecked")
 private Entry<K> readTree(
     final java.io.ObjectInputStream s, final int n, final Entry<K> pred, final Entry<K> succ)
     throws java.io.IOException, ClassNotFoundException {
   if (n == 1) {
     final Entry<K> top = new Entry<K>((K) s.readObject());
     top.pred(pred);
     top.succ(succ);
     top.black(true);
     return top;
   }
   if (n == 2) {
     /* We handle separately this case so that recursion will
      *always* be on nonempty subtrees. */
     final Entry<K> top = new Entry<K>((K) s.readObject());
     top.black(true);
     top.right(new Entry<K>((K) s.readObject()));
     top.right.pred(top);
     top.pred(pred);
     top.right.succ(succ);
     return top;
   }
   // The right subtree is the largest one.
   final int rightN = n / 2, leftN = n - rightN - 1;
   final Entry<K> top = new Entry<K>();
   top.left(readTree(s, leftN, pred, top));
   top.key = (K) s.readObject();
   top.black(true);
   top.right(readTree(s, rightN, top, succ));
   if (n + 2 == ((n + 2) & -(n + 2)))
     top.right.black(false); // Quick test for determining whether n + 2 is a power of 2.
   return top;
 }
  /**
   * Ensures that this BinarySearchTree object contains a specified element. The worstTime(n) is
   * O(n) and averageTime(n) is O(log n).
   *
   * @param element - the element whose presence is ensured in this BinarySearchTree object.
   * @return true - if this BinarySearchTree object changed as a result of this method call (that
   *     is, if element was actually inserted); otherwise, return false.
   * @throws ClassCastException - if element cannot be compared to the elements already in this
   *     BinarySearchTree object.
   * @throws NullPointerException - if element is null.
   */
  public boolean add(E element) {
    if (root == null) {
      if (element == null) throw new NullPointerException();
      root = new Entry<E>(element, null);
      size++;
      return true;
    } // empty tree
    else {
      Entry<E> temp = root;

      int comp;

      while (true) {
        comp = ((Comparable) element).compareTo(temp.element);
        if (comp == 0) return false;
        if (comp < 0)
          if (temp.left != null) temp = temp.left;
          else {
            temp.left = new Entry<E>(element, temp);
            size++;
            return true;
          } // temp.left == null
        else if (temp.right != null) temp = temp.right;
        else {
          temp.right = new Entry<E>(element, temp);
          size++;
          return true;
        } // temp.right == null
      } // while
    } // root not null
  } // method add
  /**
   * Returns the entry corresponding to the given key, if it is in the tree; <code>null</code>,
   * otherwise.
   *
   * @param k the key to search for.
   * @return the corresponding entry, or <code>null</code> if no entry with the given key exists.
   */
  private Entry<K> findKey(final K k) {
    Entry<K> e = tree;
    int cmp;

    while (e != null && (cmp = compare(k, e.key)) != 0) e = cmp < 0 ? e.left() : e.right();

    return e;
  }
 protected Entry<E> copy(Entry<? extends E> p, Entry<E> parent) {
   if (p != null) {
     Entry<E> q = new Entry<E>(p.element, parent);
     q.left = copy(p.left, q);
     q.right = copy(p.right, q);
     return q;
   } // if
   return null;
 } // method copy
 private void readObject(java.io.ObjectInputStream s)
     throws java.io.IOException, ClassNotFoundException {
   s.defaultReadObject();
   /* The storedComparator is now correctly set, but we must restore
   on-the-fly the actualComparator. */
   setActualComparator();
   allocatePaths();
   if (count != 0) {
     tree = readTree(s, count, null, null);
     Entry<K> e;
     e = tree;
     while (e.left() != null) e = e.left();
     firstEntry = e;
     e = tree;
     while (e.right() != null) e = e.right();
     lastEntry = e;
   }
   if (ASSERTS) checkTree(tree, 0, -1);
 }
  /**
   * Locates a key.
   *
   * @param k a key.
   * @return the last entry on a search for the given key; this will be the given key, if it
   *     present; otherwise, it will be either the smallest greater key or the greatest smaller key.
   */
  final Entry<K> locateKey(final K k) {
    Entry<K> e = tree, last = tree;
    int cmp = 0;

    while (e != null && (cmp = compare(k, e.key)) != 0) {
      last = e;
      e = cmp < 0 ? e.left() : e.right();
    }

    return cmp == 0 ? e : last;
  }
  @SuppressWarnings("unchecked")
  public boolean remove(final Object k) {
    if (tree == null) return false;

    Entry<K> p = tree;
    int cmp;
    int i = 0;
    final K kk = (K) k;

    while (true) {
      if ((cmp = compare(kk, p.key)) == 0) break;

      dirPath[i] = cmp > 0;
      nodePath[i] = p;

      if (dirPath[i++]) {
        if ((p = p.right()) == null) {
          // We clean up the node path, or we could have stale references later.
          while (i-- != 0) nodePath[i] = null;
          return false;
        }
      } else {
        if ((p = p.left()) == null) {
          // We clean up the node path, or we could have stale references later.
          while (i-- != 0) nodePath[i] = null;
          return false;
        }
      }
    }

    if (p.left == null) firstEntry = p.next();
    if (p.right == null) lastEntry = p.prev();

    if (p.succ()) {
      if (p.pred()) {
        if (i == 0) tree = p.left;
        else {
          if (dirPath[i - 1]) nodePath[i - 1].succ(p.right);
          else nodePath[i - 1].pred(p.left);
        }
      } else {
        p.prev().right = p.right;

        if (i == 0) tree = p.left;
        else {
          if (dirPath[i - 1]) nodePath[i - 1].right = p.left;
          else nodePath[i - 1].left = p.left;
        }
      }
    } else {
      boolean color;
      Entry<K> r = p.right;

      if (r.pred()) {
        r.left = p.left;
        r.pred(p.pred());
        if (!r.pred()) r.prev().right = r;
        if (i == 0) tree = r;
        else {
          if (dirPath[i - 1]) nodePath[i - 1].right = r;
          else nodePath[i - 1].left = r;
        }

        color = r.black();
        r.black(p.black());
        p.black(color);
        dirPath[i] = true;
        nodePath[i++] = r;
      } else {
        Entry<K> s;
        int j = i++;

        while (true) {
          dirPath[i] = false;
          nodePath[i++] = r;
          s = r.left;
          if (s.pred()) break;
          r = s;
        }

        dirPath[j] = true;
        nodePath[j] = s;

        if (s.succ()) r.pred(s);
        else r.left = s.right;

        s.left = p.left;

        if (!p.pred()) {
          p.prev().right = s;
          s.pred(false);
        }

        s.right(p.right);

        color = s.black();
        s.black(p.black());
        p.black(color);

        if (j == 0) tree = s;
        else {
          if (dirPath[j - 1]) nodePath[j - 1].right = s;
          else nodePath[j - 1].left = s;
        }
      }
    }

    int maxDepth = i;

    if (p.black()) {
      for (; i > 0; i--) {
        if (dirPath[i - 1] && !nodePath[i - 1].succ()
            || !dirPath[i - 1] && !nodePath[i - 1].pred()) {
          Entry<K> x = dirPath[i - 1] ? nodePath[i - 1].right : nodePath[i - 1].left;

          if (!x.black()) {
            x.black(true);
            break;
          }
        }

        if (!dirPath[i - 1]) {
          Entry<K> w = nodePath[i - 1].right;

          if (!w.black()) {
            w.black(true);
            nodePath[i - 1].black(false);

            nodePath[i - 1].right = w.left;
            w.left = nodePath[i - 1];

            if (i < 2) tree = w;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = w;
              else nodePath[i - 2].left = w;
            }

            nodePath[i] = nodePath[i - 1];
            dirPath[i] = false;
            nodePath[i - 1] = w;
            if (maxDepth == i++) maxDepth++;

            w = nodePath[i - 1].right;
          }

          if ((w.pred() || w.left.black()) && (w.succ() || w.right.black())) {
            w.black(false);
          } else {
            if (w.succ() || w.right.black()) {
              Entry<K> y = w.left;

              y.black(true);
              w.black(false);
              w.left = y.right;
              y.right = w;
              w = nodePath[i - 1].right = y;

              if (w.succ()) {
                w.succ(false);
                w.right.pred(w);
              }
            }

            w.black(nodePath[i - 1].black());
            nodePath[i - 1].black(true);
            w.right.black(true);

            nodePath[i - 1].right = w.left;
            w.left = nodePath[i - 1];

            if (i < 2) tree = w;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = w;
              else nodePath[i - 2].left = w;
            }

            if (w.pred()) {
              w.pred(false);
              nodePath[i - 1].succ(w);
            }
            break;
          }
        } else {
          Entry<K> w = nodePath[i - 1].left;

          if (!w.black()) {
            w.black(true);
            nodePath[i - 1].black(false);

            nodePath[i - 1].left = w.right;
            w.right = nodePath[i - 1];

            if (i < 2) tree = w;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = w;
              else nodePath[i - 2].left = w;
            }

            nodePath[i] = nodePath[i - 1];
            dirPath[i] = true;
            nodePath[i - 1] = w;
            if (maxDepth == i++) maxDepth++;

            w = nodePath[i - 1].left;
          }

          if ((w.pred() || w.left.black()) && (w.succ() || w.right.black())) {
            w.black(false);
          } else {
            if (w.pred() || w.left.black()) {
              Entry<K> y = w.right;

              y.black(true);
              w.black(false);
              w.right = y.left;
              y.left = w;
              w = nodePath[i - 1].left = y;

              if (w.pred()) {
                w.pred(false);
                w.left.succ(w);
              }
            }

            w.black(nodePath[i - 1].black());
            nodePath[i - 1].black(true);
            w.left.black(true);

            nodePath[i - 1].left = w.right;
            w.right = nodePath[i - 1];

            if (i < 2) tree = w;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = w;
              else nodePath[i - 2].left = w;
            }

            if (w.succ()) {
              w.succ(false);
              nodePath[i - 1].pred(w);
            }
            break;
          }
        }
      }

      if (tree != null) tree.black(true);
    }

    count--;
    // We clean up the node path, or we could have stale references later.
    while (maxDepth-- != 0) nodePath[maxDepth] = null;
    if (ASSERTS) {
      checkNodePath();
      checkTree(tree, 0, -1);
    }
    return true;
  }
  public boolean add(final K k) {
    int maxDepth = 0;

    if (tree == null) { // The case of the empty tree is treated separately.
      count++;
      tree = lastEntry = firstEntry = new Entry<K>(k);
    } else {
      Entry<K> p = tree, e;
      int cmp, i = 0;

      while (true) {
        if ((cmp = compare(k, p.key)) == 0) {
          // We clean up the node path, or we could have stale references later.
          while (i-- != 0) nodePath[i] = null;
          return false;
        }

        nodePath[i] = p;

        if (dirPath[i++] = cmp > 0) {
          if (p.succ()) {
            count++;
            e = new Entry<K>(k);

            if (p.right == null) lastEntry = e;

            e.left = p;
            e.right = p.right;

            p.right(e);

            break;
          }

          p = p.right;
        } else {
          if (p.pred()) {
            count++;
            e = new Entry<K>(k);

            if (p.left == null) firstEntry = e;

            e.right = p;
            e.left = p.left;

            p.left(e);

            break;
          }

          p = p.left;
        }
      }

      maxDepth = i--;

      while (i > 0 && !nodePath[i].black()) {
        if (!dirPath[i - 1]) {
          Entry<K> y = nodePath[i - 1].right;

          if (!nodePath[i - 1].succ() && !y.black()) {
            nodePath[i].black(true);
            y.black(true);
            nodePath[i - 1].black(false);
            i -= 2;
          } else {
            Entry<K> x;

            if (!dirPath[i]) y = nodePath[i];
            else {
              x = nodePath[i];
              y = x.right;
              x.right = y.left;
              y.left = x;
              nodePath[i - 1].left = y;

              if (y.pred()) {
                y.pred(false);
                x.succ(y);
              }
            }

            x = nodePath[i - 1];
            x.black(false);
            y.black(true);

            x.left = y.right;
            y.right = x;
            if (i < 2) tree = y;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = y;
              else nodePath[i - 2].left = y;
            }

            if (y.succ()) {
              y.succ(false);
              x.pred(y);
            }
            break;
          }
        } else {
          Entry<K> y = nodePath[i - 1].left;

          if (!nodePath[i - 1].pred() && !y.black()) {
            nodePath[i].black(true);
            y.black(true);
            nodePath[i - 1].black(false);
            i -= 2;
          } else {
            Entry<K> x;

            if (dirPath[i]) y = nodePath[i];
            else {
              x = nodePath[i];
              y = x.left;
              x.left = y.right;
              y.right = x;
              nodePath[i - 1].right = y;

              if (y.succ()) {
                y.succ(false);
                x.pred(y);
              }
            }

            x = nodePath[i - 1];
            x.black(false);
            y.black(true);

            x.right = y.left;
            y.left = x;
            if (i < 2) tree = y;
            else {
              if (dirPath[i - 2]) nodePath[i - 2].right = y;
              else nodePath[i - 2].left = y;
            }

            if (y.pred()) {
              y.pred(false);
              x.succ(y);
            }

            break;
          }
        }
      }
    }
    tree.black(true);
    // We clean up the node path, or we could have stale references later.
    while (maxDepth-- != 0) nodePath[maxDepth] = null;
    if (ASSERTS) {
      checkNodePath();
      checkTree(tree, 0, -1);
    }
    return true;
  }
示例#10
0
  @SuppressWarnings("unchecked")
  public boolean remove(final long k) {
    if (tree == null) return false;

    int cmp;
    Entry p = tree, q = null;
    boolean dir = false;
    final long kk = k;

    while (true) {
      if ((cmp = compare(kk, p.key)) == 0) break;
      else if (dir = cmp > 0) {
        q = p;
        if ((p = p.right()) == null) return false;
      } else {
        q = p;
        if ((p = p.left()) == null) return false;
      }
    }

    if (p.left == null) firstEntry = p.next();
    if (p.right == null) lastEntry = p.prev();

    if (p.succ()) {
      if (p.pred()) {
        if (q != null) {
          if (dir) q.succ(p.right);
          else q.pred(p.left);
        } else tree = dir ? p.right : p.left;
      } else {
        p.prev().right = p.right;

        if (q != null) {
          if (dir) q.right = p.left;
          else q.left = p.left;
        } else tree = p.left;
      }
    } else {
      Entry r = p.right;

      if (r.pred()) {
        r.left = p.left;
        r.pred(p.pred());
        if (!r.pred()) r.prev().right = r;
        if (q != null) {
          if (dir) q.right = r;
          else q.left = r;
        } else tree = r;

        r.balance(p.balance());
        q = r;
        dir = true;

      } else {
        Entry s;

        while (true) {
          s = r.left;
          if (s.pred()) break;
          r = s;
        }

        if (s.succ()) r.pred(s);
        else r.left = s.right;

        s.left = p.left;

        if (!p.pred()) {
          p.prev().right = s;
          s.pred(false);
        }

        s.right = p.right;
        s.succ(false);

        if (q != null) {
          if (dir) q.right = s;
          else q.left = s;
        } else tree = s;

        s.balance(p.balance());
        q = r;
        dir = false;
      }
    }

    Entry y;

    while (q != null) {
      y = q;
      q = parent(y);

      if (!dir) {
        dir = q != null && q.left != y;
        y.incBalance();

        if (y.balance() == 1) break;
        else if (y.balance() == 2) {

          Entry x = y.right;
          if (ASSERTS) assert x != null;

          if (x.balance() == -1) {
            Entry w;

            if (ASSERTS) assert x.balance() == -1;

            w = x.left;
            x.left = w.right;
            w.right = x;
            y.right = w.left;
            w.left = y;

            if (w.balance() == 1) {
              x.balance(0);
              y.balance(-1);
            } else if (w.balance() == 0) {
              x.balance(0);
              y.balance(0);
            } else {
              if (ASSERTS) assert w.balance() == -1;

              x.balance(1);
              y.balance(0);
            }

            w.balance(0);

            if (w.pred()) {
              y.succ(w);
              w.pred(false);
            }
            if (w.succ()) {
              x.pred(w);
              w.succ(false);
            }

            if (q != null) {
              if (dir) q.right = w;
              else q.left = w;
            } else tree = w;
          } else {
            if (q != null) {
              if (dir) q.right = x;
              else q.left = x;
            } else tree = x;

            if (x.balance() == 0) {
              y.right = x.left;
              x.left = y;
              x.balance(-1);
              y.balance(+1);
              break;
            }

            if (ASSERTS) assert x.balance() == 1;

            if (x.pred()) {
              y.succ(true);
              x.pred(false);
            } else y.right = x.left;

            x.left = y;
            y.balance(0);
            x.balance(0);
          }
        }
      } else {
        dir = q != null && q.left != y;
        y.decBalance();

        if (y.balance() == -1) break;
        else if (y.balance() == -2) {

          Entry x = y.left;
          if (ASSERTS) assert x != null;

          if (x.balance() == 1) {
            Entry w;

            if (ASSERTS) assert x.balance() == 1;

            w = x.right;
            x.right = w.left;
            w.left = x;
            y.left = w.right;
            w.right = y;

            if (w.balance() == -1) {
              x.balance(0);
              y.balance(1);
            } else if (w.balance() == 0) {
              x.balance(0);
              y.balance(0);
            } else {
              if (ASSERTS) assert w.balance() == 1;

              x.balance(-1);
              y.balance(0);
            }

            w.balance(0);

            if (w.pred()) {
              x.succ(w);
              w.pred(false);
            }
            if (w.succ()) {
              y.pred(w);
              w.succ(false);
            }

            if (q != null) {
              if (dir) q.right = w;
              else q.left = w;
            } else tree = w;
          } else {
            if (q != null) {
              if (dir) q.right = x;
              else q.left = x;
            } else tree = x;

            if (x.balance() == 0) {
              y.left = x.right;
              x.right = y;
              x.balance(+1);
              y.balance(-1);
              break;
            }

            if (ASSERTS) assert x.balance() == -1;

            if (x.succ()) {
              y.pred(true);
              x.succ(false);
            } else y.left = x.right;

            x.right = y;
            y.balance(0);
            x.balance(0);
          }
        }
      }
    }

    count--;
    if (ASSERTS) checkTree(tree);
    return true;
  }
示例#11
0
  public boolean add(final long k) {

    if (tree == null) { // The case of the empty tree is treated separately.
      count++;
      tree = lastEntry = firstEntry = new Entry(k);
    } else {
      Entry p = tree, q = null, y = tree, z = null, e = null, w = null;
      int cmp, i = 0;

      while (true) {
        if ((cmp = compare(k, p.key)) == 0) return false;

        if (p.balance() != 0) {
          i = 0;
          z = q;
          y = p;
        }

        if (dirPath[i++] = cmp > 0) {
          if (p.succ()) {
            count++;
            e = new Entry(k);

            if (p.right == null) lastEntry = e;

            e.left = p;
            e.right = p.right;

            p.right(e);

            break;
          }

          q = p;
          p = p.right;
        } else {
          if (p.pred()) {
            count++;
            e = new Entry(k);

            if (p.left == null) firstEntry = e;

            e.right = p;
            e.left = p.left;

            p.left(e);

            break;
          }

          q = p;
          p = p.left;
        }
      }

      p = y;
      i = 0;

      while (p != e) {
        if (dirPath[i]) p.incBalance();
        else p.decBalance();

        p = dirPath[i++] ? p.right : p.left;
      }

      if (y.balance() == -2) {
        Entry x = y.left;

        if (x.balance() == -1) {
          w = x;
          if (x.succ()) {
            x.succ(false);
            y.pred(x);
          } else y.left = x.right;

          x.right = y;
          x.balance(0);
          y.balance(0);
        } else {
          if (ASSERTS) assert x.balance() == 1;

          w = x.right;
          x.right = w.left;
          w.left = x;
          y.left = w.right;
          w.right = y;
          if (w.balance() == -1) {
            x.balance(0);
            y.balance(1);
          } else if (w.balance() == 0) {
            x.balance(0);
            y.balance(0);
          } else {
            x.balance(-1);
            y.balance(0);
          }
          w.balance(0);

          if (w.pred()) {
            x.succ(w);
            w.pred(false);
          }
          if (w.succ()) {
            y.pred(w);
            w.succ(false);
          }
        }
      } else if (y.balance() == +2) {
        Entry x = y.right;

        if (x.balance() == 1) {
          w = x;
          if (x.pred()) {
            x.pred(false);
            y.succ(x);
          } else y.right = x.left;

          x.left = y;
          x.balance(0);
          y.balance(0);
        } else {
          if (ASSERTS) assert x.balance() == -1;

          w = x.left;
          x.left = w.right;
          w.right = x;
          y.right = w.left;
          w.left = y;
          if (w.balance() == 1) {
            x.balance(0);
            y.balance(-1);
          } else if (w.balance() == 0) {
            x.balance(0);
            y.balance(0);
          } else {
            x.balance(1);
            y.balance(0);
          }
          w.balance(0);

          if (w.pred()) {
            y.succ(w);
            w.pred(false);
          }
          if (w.succ()) {
            x.pred(w);
            w.succ(false);
          }
        }
      } else return true;

      if (z == null) tree = w;
      else {
        if (z.left == y) z.left = w;
        else z.right = w;
      }
    }

    if (ASSERTS) checkTree(tree);
    return true;
  }