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
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.