Search code examples
dictionarydata-structurestime-complexityhashtablehash-collision

Hash Table separate chaining restore insertion order after removal


Is it possible to restore the insertion order of elements to the Hash Table with separate chaining collision resolution while preserving O(n) removal time complexity?

For example, I store Linked Lists in an array. On each insertion, I calculate the index of the list to add in and put the new value to the end of this list. Later I remove some values by calculating index and removing it from the list with that index. After these operations, I would like to iterate over the Hash Table in the same order the values were added.

If I store keys and values in additional 2 arrays I can save the insertion order, but removal will take O(n) time (while removing must first find the index of the key/value in the array what takes linear time)

Thanks a lot!


Solution

  • It is not possible to "iterate over the Hash Table in the same order the values were added". (For separate chaining as you describe, you can easily guarantee insertion-order iteration of each group of elements that collided at the same hash bucket, but that's a very different property.)

    If I store keys and values in additional 2 arrays I can save the insertion order, but removal will take O(n) time (while removing must first find the index of the key/value in the array what takes linear time)

    You can have your hash map record the index, so on removal you know which insertion-order-array position to remove. But, if you compact the array (moving trailing elements up one to fill the gap) when removing an element, you end up with O(N) behaviour anyway.

    If there's little churn in your data - and the number of insertions done isn't much higher than the number of elements at the time of iteration, you could just overwrite the entries in the 2 additional arrays with sentinel values to say they can be ignored during iteration, without recompacting.

    Ultimately though, you may be best off using a balanced binary tree keyed on a number that you increment when inserting. If the hash map stores iterators into that tree, you can remove elements easily. Most operations are O(logN).