Developing the Data Structure

The basis and motivation for finger trees comes from 2-3 trees. 2-3 trees are trees which can have two or three branches at each internal node and which have all of their leaves at the same level. While a binary tree of uniform depth $d$ must have $2^d$ leaves, 2-3 trees are much more flexible, and may be used to store any number of elements (the number does not have to be a power of two).

Consider the following 2-3 tree (image taken from the original finger-tree paper linked above):

This tree stores fourteen elements. Access to any of them requires three steps, and if we were to add more elements, the number of steps for each one would grow logarithmically. We would like to use these trees in order to model sequences. However, in many application sequences are very often accessed repeatedly at the front or back, and much less often in the middle. To accomodate this use case, we can modify this data structure to prioritize front and back access over other features.

In our case, we add two fingers. A finger is simply a point at which you can access part of a data structure; in imperative languages, this would simply be a pointer. In our case, though, we restructure the entire tree and make the parents of the first and last children the two roots of our tree. Visually, consider taking the tree above, grabbing the first and last nodes on the previous-to-last layer, and pulling them up, letting the rest of the tree hang down:

This new data structure is known as a finger tree. The finger tree is composed of several layers (boxed in blue below) which sit along its spine (the brown line):

Each layer of the finger tree has a prefix (on the left) and a suffix (on the right), as well as a link further down the spine. The prefix and suffix contain values in the finger tree – on the first level, they contain values (2-3 trees of depth 0); on the second level, they contain 2-3 trees of depth 1; on the third level, they contain 2-3 trees of depth 2, and so on. This somewhat unusual property comes from the fact that the original 2-3 tree was of uniform depth. The edges of the original 2-3 tree are now at the top of the spine. The root of the 2-3 tree is now the very bottom element of the spine. As we go down the spine, we are traversing from the leaves to the root of the original 2-3 tree; as we go closer to the root, the prefix and suffixes contain deeper and deeper subtrees of the original 2-3 tree.

With this description out of the way, let's go ahead and define this data structure. First, we must define the 2-3 tree structure which will be used to store things hanging off the spine: