Ruby- delete a value from sorted (unique) array at O(log n) runtime

前端 未结 1 762
余生分开走
余生分开走 2021-01-21 09:26

I have a sorted array (unique values, not duplicated).

I know I can use Array#binarysearch but it\'s used to find values not delete them. Can I delete a value at O(log n

1条回答
  •  清歌不尽
    2021-01-21 10:07

    The standard Array implementation has no constraint on sorting or duplicate. Therefore, the default implementation has to trade performance with flexibility.

    Array#delete deletes an element in O(n). Here's the C implementation. Notice the loop

    for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
      ...
    }
    

    The cost is justified by the fact Ruby has to scan all the items matching given value (note delete deletes all the entries matching a value, not just the first), then shift the next items to compact the array.

    delete_at has the same cost. In fact, it deletes the element by given index, but then it uses memmove to shift the remaining entries one index less on the array.

    Using a binary search will not change the cost. The search will cost you O(log n), but you will need to delete the element at given key. In the worst case, when the element is in position [0], the cost to shift all the other items in memory by 1 position will be O(n).

    In all cases, the cost is O(n). This is not unexpected. The default array implementation in Ruby uses arrays. And that's because, as said before, there are no specific constraints that could be used to optimize operations. Easy iteration and manipulation of the collection is the priority.

    Array, sorted array, list and sorted list: all these data structures are flexible, but you pay the cost in some specific operations.

    Back to your question, if you care about performance and your array is sorted and unique, you can definitely take advantage of it. If your primary goal is finding and deleting items from your array, there are better data structures. For instance, you can create a custom class that stores your array internally using a d-heap where the delete() costs O(log[d,n]), same applies if you use a binomial heap.

    0 讨论(0)
提交回复
热议问题