0

I have implemented an indexed linked list that runs (under mild assumptions) all single-element operations in $\mathcal{O}(\sqrt{n})$ time. The description is here and Java implementation is here.

It’s clear to me that the running time is linear in $n$ in the worst case, but I would love to see something smarter than that.

The idea is to maintain a list of fingers. Each finger $f$ has two fields: (1) $f.node$ pointing to a linked list node, and (2) $f.index$ being the actual index of the node pointed by $f.node$.

Now, the finger list has size $\lceil \sqrt{n} \rceil$, and it’s sorted by finger indices. Given an element index $i$, we can access it as follows:

Apply C++ lower_bound to find the closest to $i$ finger $f$, and ”rewind” $f.node$ to point to the $i$th node. (Set $f.index \leftarrow i$ also.) This applies to the get operation and runs in logarithmic time. Assuming that the fingers are distributed more or less evenly, rewinding will run in $\mathcal{O}(n / \sqrt{n} = \sqrt{n})$ time.

For the insert/removeAt operations, both do (1) finger list lookup in logarithmic time, (2) finger node rewind in $\mathcal{O}(\sqrt{n})$, and (3) also update the finger indices that runs in, too, $\mathcal{O}(\sqrt{n})$.

coderodde
  • 60
  • 1
  • 13

1 Answers1

0

Suppose we are appending elements to the tail of the list. Suppose also that the rightmost finger has index $f$. Now, the distance between $f$ and the second rightmost finger $f - 1$ (which should be the largest since we are comparing two rightmost fingers (the distance between adjacent fingers grows as we scan the fingers from left to right)), is given by $$ \begin{aligned} f^2 - (f-1)^2 &= f^2 - (f^2 - 2f + 1) \\ &= 2f - 1 \\ &\overset{1}{=} 2\Big\lceil \sqrt{n} \Big\rceil -1\\ &= \Theta(\sqrt{n}). \end{aligned} $$ We conclude that appending all the elements one by one keeps the finger indices (in asymptotic sense) evenly distributed.

(Above, we have (1) by the data structure invariant.)

coderodde
  • 60
  • 1
  • 13