0

Is there a data structure with the following operations?

  • get(idx) -> Item gets the item at index idx.
  • insert(idx, item) inserts item at index idx in the structure. Should be O(log N) worst case.
  • delete(idx) deletes item at index idx.
  • track_index(idx) -> Handle gives a "handle" associated with the item at idx, so that I can later use the next function to ask what the index of that item is.
  • retrieve_index(handle) -> index returns the current index of the item associated with the handle created by the previous function.

I would like all of these to have O(log N) worst-case runtime.

I already have an idea on how to implement it (I'm thinking AVL tree with each node storing the number of its left and right descendants), but I want to know if there is already a name for something like this, or if it is possible to repurpose some other common data structures to get these operations.

EDIT: My item data type is not totally nor partially ordered.

wisha
  • 643
  • 1
  • 6
  • 12
  • Related and probably helpful: https://stackoverflow.com/questions/10955972/avl-trees-how-to-do-index-access – Jerry Jeremiah Sep 02 '22 at 01:08
  • @JerryJeremiah indeed the answer to that question is the same thing I had in mind. From that thread it seems that there is no specific name for this data structure. I'll have to implement my own then :) – wisha Sep 02 '22 at 01:12
  • Your idea is a good one. It's called an order statistic tree: https://en.wikipedia.org/wiki/Order_statistic_tree You only need to store one count per node. – Matt Timmermans Sep 02 '22 at 03:36
  • How meaningful should the indexes be? Why is there a distinction between "indexes" and "handles"? It looks like the "indexes" and the "handles" play a redundant role. – Stef Sep 02 '22 at 09:28
  • Also note that for question about abstract data structures like this, https://cs.stackexchange.com might be a much better resource than StackOverflow. – Stef Sep 02 '22 at 09:29
  • @Stef the idea is that first I put in an item `x` at index `i`, and get a handle `h` to it, then insert and delete other items elsewhere in the list, causing the index of `x` to change. I can no longer access `x` with `i`, but I want to be able to use `h` to ask what the new index of `x` is. – wisha Sep 05 '22 at 15:52
  • @wisha: what is `i` for in this scenario? just insert at a handle `h` directly – Stef Sep 05 '22 at 15:55
  • @Stef If all lookups and inserts can be specified by "handle" then a linked list would work just fine. Unfortunately I need to be able to lookup and insert by index, which may change when the list is modified elsewhere. – wisha Sep 05 '22 at 16:02

2 Answers2

2

You can use any of the self-balancing search trees (AVL, red-black, B-tree, B+-tree, ...) and augment their nodes with a node count attribute which is kept updated during manipulations. Similarly, you can augment a Skip List with such properties.

This will allow for retrieving/inserting/removing elements by their index with O(logn) time complexity.

The "handle" would be the pointer to where the value is found in the tree, and by threading the tree (i.e. including parent pointers), such handle gives complete information as to where the value is in the tree, allowing for getting its index, its predecessor or successor.

trincot
  • 317,000
  • 35
  • 244
  • 286
0

One option for a data structure with these properties is a balanced binary search tree. This type of tree has O(log N) insertion, deletion, and search time complexity, as well as the ability to track the indices of items in the tree.

  • My item data are not totally ordered (in fact not even partially ordered), so I don't think a direct application of binary search tree would work. One possible way would be to add an [order-maintenance](https://en.wikipedia.org/wiki/Order-maintenance_problem) data structure to give them order, but that is way more complex than what I'm looking for. – wisha Sep 02 '22 at 01:07