public boolean add(T x) { int i, c = 0, ix = it.intValue(x); Node u = r; // 1 - search for ix until falling out of the trie for (i = 0; i < w; i++) { c = (ix >>> w - i - 1) & 1; if (u.child[c] == null) break; u = u.child[c]; } if (i == w) return false; // already contains x - abort Node pred = (c == right) ? u.jump : u.jump.child[0]; u.jump = null; // u will have two children shortly // 2 - add path to ix for (; i < w; i++) { c = (ix >>> w - i - 1) & 1; u.child[c] = newNode(); u.child[c].parent = u; u = u.child[c]; } u.x = x; // 3 - add u to linked list u.child[prev] = pred; u.child[next] = pred.child[next]; u.child[prev].child[next] = u; u.child[next].child[prev] = u; // 4 - walk back up, updating jump pointers Node v = u.parent; while (v != null) { if ((v.child[left] == null && (v.jump == null || it.intValue(v.jump.x) > ix)) || (v.child[right] == null && (v.jump == null || it.intValue(v.jump.x) < ix))) v.jump = u; v = v.parent; } n++; return true; }
protected void checkList() { Node u = dummy.child[right]; do { if (u.child[right] != dummy) Utils.myassert(it.intValue(u.x) < it.intValue(u.child[right].x)); Utils.myassert(u.child[left].child[right] == u); Utils.myassert(u.child[right].child[left] == u); u = u.child[right]; } while (u != dummy); }
public boolean remove(T x) { // 1 - find leaf, u, containing x int i, c, ix = it.intValue(x); Node u = r; for (i = 0; i < w; i++) { c = (ix >>> w - i - 1) & 1; if (u.child[c] == null) return false; u = u.child[c]; } // 2 - remove u from linked list u.child[prev].child[next] = u.child[next]; u.child[next].child[prev] = u.child[prev]; Node v = u; // 3 - delete nodes on path to u for (i = w - 1; i >= 0; i--) { c = (ix >>> w - i - 1) & 1; v = v.parent; v.child[c] = null; if (v.child[1 - c] != null) break; } // 4 - update jump pointers c = (ix >>> w - i - 1) & 1; v.jump = u.child[1 - c]; v = v.parent; i--; for (; i >= 0; i--) { c = (ix >>> w - i - 1) & 1; if (v.jump == u) v.jump = u.child[1 - c]; v = v.parent; } n--; return true; }
public T find(T x) { int i, c = 0, ix = it.intValue(x); Node u = r; for (i = 0; i < w; i++) { c = (ix >>> w - i - 1) & 1; if (u.child[c] == null) break; u = u.child[c]; } if (i == w) return u.x; // found it u = (c == 0) ? u.jump : u.jump.child[next]; return u == dummy ? null : u.x; }
/** * Find the node in the doubly-linked list that comes before the node that contains (the successor * of) x * * @param x * @return The node before the node that contains x in the linked list */ protected Node findPredNode(T x) { int i, c = 0, ix = it.intValue(x); Node u = r; for (i = 0; i < w; i++) { c = (ix >>> w - i - 1) & 1; if (u.child[c] == null) break; u = u.child[c]; } Node pred; if (i == w) pred = u.child[prev]; else pred = (c == 1) ? u.jump : u.jump.child[0]; return pred; }