Algorithm Search⌘K

Proofs: Tango tree

These are the human proofs of Tango tree, at full length.

The number of preferred path changes in a tango tree is the interleave bound full

This proof shows: complexity, competitive-ratio.

Fix the reference tree PP and an access sequence X=x1,…,xmX = x_1, \ldots, x_m. For a node yy, list the accesses xix_i with xi∈I(y)x_i \in I(y), the key interval of the subtree of yy, and label each LL if xi≤yx_i \le y and RR otherwise. Let ib(y)\mathrm{ib}(y) be the number of changes of label along this list, and IB(X)=∑yib(y)\mathrm{IB}(X) = \sum_y \mathrm{ib}(y), the interleave bound.

Lemma 1. The preferred child of yy after access ii is left if the last access in I(y)I(y) up to time ii is labelled LL, right if it is labelled RR, and none if there is none.

Proof. By the correctness proof, access ii changes the preferred children exactly of the nodes on the root-to-xix_i path of PP, which are the nodes yy with xi∈I(y)x_i \in I(y), and sets them to the side of xix_i: left for xi≤yx_i \le y (including xi=yx_i = y, by line L11), right for xi>yx_i > y. That is the label of xix_i at yy. □\square

Theorem 1. The number of L-R switches (changes of a preferred child from left to right or from right to left) over the whole sequence is exactly IB(X)\mathrm{IB}(X).

Proof. By Lemma 1, the preferred child of yy changes between left and right exactly when two consecutive accesses in I(y)I(y) have different labels, which is one change counted in ib(y)\mathrm{ib}(y). Sum over yy. □\square

Theorem 2. Access ii visits at most ki+fi+1k_i + f_i + 1 paths, where kik_i is its number of L-R switches and fif_i the number of nodes that get their first preferred child during access ii. So the total number of paths visited is at most IB(X)+m+n\mathrm{IB}(X) + m + n.

Proof. Each path visited after the first is entered from a pair (u,c)(u, c) of line L6, and uu then changes its preferred child: from the other side (an L-R switch) or from none (a first choice). Different pairs have different uu. A node gets its first preferred child only once. Sum and use Theorem 1. □\square

Theorem 3 (cost). If each auxiliary tree is a red-black tree with depth fields, so that a search, a cut and a join on a path of at most lg⁡n+1\lg n + 1 nodes take O(log⁡log⁡n)O(\log \log n) time, then the total cost is O((IB(X)+m+n)(1+log⁡log⁡n))O((\mathrm{IB}(X) + m + n)(1 + \log \log n)), and so O((OPT(X)+n)(1+log⁡log⁡n))O((\mathrm{OPT}(X) + n)(1 + \log \log n)).

Proof. Each visited path costs one search, and each pair (u,c)(u, c) and line L11 cost one cut and one join, all in trees of O(log⁡n)O(\log n) nodes. By Theorem 2 the number of these is O(IB(X)+m+n)O(\mathrm{IB}(X) + m + n). Wilber's first lower bound, in the form proved by Demaine, Harmon, Iacono and Pătraşcu, is OPT(X)≥IB(X)/2−n\mathrm{OPT}(X) \ge \mathrm{IB}(X)/2 - n, and OPT(X)≥m\mathrm{OPT}(X) \ge m since each access touches a node. So IB(X)+m+n≤2 OPT(X)+2n+OPT(X)+n=O(OPT(X)+n)\mathrm{IB}(X) + m + n \le 2\,\mathrm{OPT}(X) + 2n + \mathrm{OPT}(X) + n = O(\mathrm{OPT}(X) + n). ■\blacksquare

The time bound of a search, cut and join in O(log⁡log⁡n)O(\log \log n) is the part this page does not prove; it is the standard cost of split and concatenate of red-black trees of size O(log⁡n)O(\log n), with the depth fields used to find the range to cut, as in the paper of Demaine, Harmon, Iacono and Pătraşcu. In the Python code, the search is a binary search on a sorted list, with at most ⌈lg⁡(lg⁡n+2)⌉\lceil \lg(\lg n + 2) \rceil comparisons, and the tests check this count; the cut and the join are list slices.

Tango tree access finds the key and keeps the preferred paths full

This proof shows: correctness, invariant, termination.

Write PP for the reference tree, I(y)I(y) for the key interval of the subtree of yy in PP, and pc(y)\mathrm{pc}(y) for the preferred child of yy (a child of yy or none). A path is a chain v0,v1,…,vtv_0, v_1, \ldots, v_t with vj+1=pc(vj)v_{j+1} = \mathrm{pc}(v_j) and pc(vt)\mathrm{pc}(v_t) none or missing, where v0v_0 is the root of PP or a child that its parent does not prefer. The invariant (T1, T2) says the stored paths are exactly these chains, as sorted key sets, indexed by their tops.

Lemma 1. The paths partition the nodes of PP. For a path AA with top v0v_0, all keys of AA lie in I(v0)I(v_0), and for each jj, the nodes of AA below vjv_j are exactly the nodes of AA with keys in I(pc(vj))I(\mathrm{pc}(v_j)).

Proof. Each node yy is on exactly one path: follow parents up while the parent prefers the current node; the node where this stops is the top, and yy is on its chain. The keys of a chain from v0v_0 are in I(v0)I(v_0). The nodes below vjv_j on the chain are in the subtree of pc(vj)\mathrm{pc}(v_j), and the nodes v0,…,vjv_0, \ldots, v_j are ancestors of pc(vj)\mathrm{pc}(v_j), whose keys are not in I(pc(vj))I(\mathrm{pc}(v_j)). □\square

Lemma 2 (exit node). Let AA be a path with top v0v_0, with x∈I(v0)x \in I(v_0) and xx not on AA. Let uu be the deepest node of AA with x∈I(u)x \in I(u), and cc the child of uu on the side of xx. Then uu is the deeper of the predecessor and the successor of xx among the keys of AA, cc exists, cc is not preferred by uu, and cc is the top of a path with x∈I(c)x \in I(c).

Proof. uu exists since x∈I(v0)x \in I(v_0). Say x<ux < u; the other case is symmetric. Then x∈I(c)x \in I(c) for the left child cc of uu, which exists since I(c)=[min⁡I(u),u−1]I(c) = [\min I(u), u - 1] holds xx. If pc(u)=c\mathrm{pc}(u) = c, then cc is on AA and is deeper than uu with x∈I(c)x \in I(c), which contradicts the choice of uu; so cc is not preferred and is the top of a path. The nodes of AA in I(u)I(u) are uu and the nodes below uu, which are in I(pc(u))I(\mathrm{pc}(u)) by Lemma 1; that is the right subtree of uu (or empty). So no key of AA is in (x,u)(x, u), and uu is the successor of xx on AA. The predecessor, if any, is a key of AA smaller than xx, hence outside I(u)I(u), hence an ancestor of uu: shallower. □\square

Termination and the result of the search. At the start, AA holds the root, and x∈I(root)x \in I(\text{root}). By Lemma 2, each round of lines L5 to L7 moves to a path whose top cc has x∈I(c)x \in I(c) and is deeper than before. The depth is bounded, so the loop stops, and it stops only at line L4, when xx is on AA. The pairs (u,c)(u, c) recorded are exactly the nodes uu on the root-to-xx path of PP whose preferred child is not on the side of xx, with cc the child on the side of xx: on each path visited, the nodes of the root-to-xx path above uu have their preferred child toward xx (they are followed by the next node of AA, which is on the way to xx because uu is below them with x∈I(u)x \in I(u)).

Updates. Take the pairs from the top down. Before the update for (u,c)(u, c), the path that holds uu contains the root of PP (by induction: the first uu is on the root path, and each join adds the next path below the previous uu). By Lemma 1, CUT removes exactly the nodes of that path below uu; they form the chain from the old pc(u)\mathrm{pc}(u), whose parent will no longer prefer it, so they form a path with that top, as (T2) needs. JOIN adds the path with top cc, whose keys are in I(c)I(c), a range that holds no other key of the upper part (it is in the subtree of uu, and the upper part has no node below uu now). After setting pc(u)=c\mathrm{pc}(u) = c, the chain from the root follows cc and then the chain of cc, which is the joined path, and cc is no longer a top. So (T1) and (T2) hold after each pair. Line L11 does the same at xx with the left child. After the access, every node yy on the root-to-xx path has pc(y)\mathrm{pc}(y) on the side of xx, and pc(x)\mathrm{pc}(x) is left, which is the definition of preferred children after an access to xx; all other preferred children are unchanged, as the definition requires, since the most recent access in their subtrees is unchanged. ■\blacksquare

Back to Tango tree