2 ms·
There's an O(log N) data structure for this. Unfortunately I don't know the name of it. Keep a (balanced) binary tree where each node contains a pointer to one
by adrianmonk 9y ago
There's an O(log N) data structure for this. Unfortunately I don't know the name of it.
Keep a (balanced) binary tree where each node contains a pointer to one of the items you want to keep ordered. (In this case, each node has the primary key of one of your database rows.)
Every node also contains an integer which tells the size of that subtree (the tree whose root is that node).
To enumerate the entire list, do an in-order traversal of the tree.
To find the Nth item in the list, check the left child to see if it contains enough nodes that your Nth item would be in that subtree. If so, go left. If not, it's either the current node (if off by exactly one) or you go right. But if you go right, you must reduce N by 1 to account for the current node and also reduce N by the size of the left subtree.
To enumerate a range, you basically combine the previous two.
To move an item, just move it in the normal way you'd delete/add a node in any regular tree, but remember to update the counts stored inside any nodes that are affected, i.e. all parents/ancestors of any node that is removed or added. If you delete an internal node, you need to be careful to preserve the order of everything, but there are ways to do that by exchange
This data structure can definitely be modeled in database tables. Whether the operations on it can all be expressed in SQL is an interesting question. It might be impossible, or it might just be really tricky.