Esempio n. 1
0
  void redirectThreadsPointingToMe(FHthreadedNode<E> nodeToRemove) {
    FHthreadedNode<E> minNode, maxNode, node;

    // adjust nodes in root's subtree that "thread directly up" to root
    minNode = findMin(nodeToRemove);
    maxNode = findMax(nodeToRemove);

    for (node = minNode; node != null; node = successor(node))
      if (node.lftThread && node.lftChild == nodeToRemove) {
        node.lftChild = predecessor(nodeToRemove);
        break; // last of only two possible threads pointing up
      } else if (node.rtThread && node.rtChild == nodeToRemove) {
        node.rtChild = successor(nodeToRemove);
      }
  }
Esempio n. 2
0
  // called when both flags are true, meaning one MUST be parent. find out
  // which one, so we can set parent's left of right thread flag to true
  protected FHthreadedNode<E> adjustParentThreadFlagsAndUnlink(FHthreadedNode<E> nodeToRemove) {
    FHthreadedNode<E> node;

    node = nodeToRemove.rtChild; // successor is parent?
    if (node != null) {
      if (node.lftChild == nodeToRemove) {
        node.lftThread = true;
        return nodeToRemove.lftChild;
      }
    }

    // test both in case mRoot is leaf
    node = nodeToRemove.lftChild; // predecessor is parent?
    if (node != null) {
      if (node.rtChild == nodeToRemove) {
        node.rtThread = true;
        return nodeToRemove.rtChild;
      }
    }

    return null; // shouldn't happen
  }
Esempio n. 3
0
  public boolean insert(E x) {
    int compareResult;

    if (mRoot == null) {
      mRoot = new FHthreadedNode<E>(x, null, null, true, true, 0);
      mSize++;
      return true;
    }

    FHthreadedNode<E> newNode, parent;
    parent = mRoot;

    while (true) {
      compareResult = x.compareTo(parent.data);
      if (compareResult < 0) {
        if (!(parent.lftThread)) parent = parent.lftChild;
        else {
          // place as new left child
          newNode = new FHthreadedNode<E>(x, parent.lftChild, parent, true, true, 0);
          parent.lftChild = newNode;
          parent.lftThread = false;
          break;
        }
      } else if (compareResult > 0) {
        if (!(parent.rtThread)) parent = parent.rtChild;
        else {
          // place as new right child
          newNode = new FHthreadedNode<E>(x, parent, parent.rtChild, true, true, 0);
          parent.rtChild = newNode;
          parent.rtThread = false;
          break;
        }
      } else return false; // duplicate
    }

    mSize++;
    return true;
  }
Esempio n. 4
0
  // very hard to remove recursion, so only adjust pred/succ links
  protected FHthreadedNode<E> remove(FHthreadedNode<E> root, E x) {
    int compareResult; // avoid multiple calls to compareTo()
    FHthreadedNode<E> tempRoot;

    if (root == null) return null;

    compareResult = x.compareTo(root.data);
    if (compareResult < 0) {
      if (!root.lftThread) root.lftChild = remove(root.lftChild, x);
    } else if (compareResult > 0) {
      if (!root.rtThread) root.rtChild = remove(root.rtChild, x);
    }

    // found the node
    else if (!(root.lftThread) && !(root.rtThread)) {
      // two real children
      root.data = findMin(root.rtChild).data;
      root.rtChild = remove(root.rtChild, root.data);
    } else {
      // one or two "fake" children => at least one thread
      redirectThreadsPointingToMe(root);

      // if a full leaf, we have to modify one of parent's thread flags
      if (root.lftThread && root.rtThread) {
        tempRoot = adjustParentThreadFlagsAndUnlink(root);

        // in case this was final node in tree
        if (root.lftChild == null && root.rtChild == null) mRoot = null;

        root = tempRoot;
      } else
        // at least one real child, so we copy to parent
        root = (!(root.lftThread)) ? root.lftChild : root.rtChild;

      mSize--;
    }
    return root;
  }