0

I have a SplMaxHeap with 30 items. Now I want to strip the last 10 ones. How to do this in a decent and efficient way?

The only solutions I see so far is to copy the first 20 items to a new heap or to convert the heap to an array, use the array_slice and put them also in a new heap.

I even can't see a way to get something out of the heap not from the top.

I guess the reason for this is a limitation of the general design of a heap? I was also thinking to use a DoublyLinkedList, however there I am missing the automatic sorting.

flori
  • 14,339
  • 4
  • 56
  • 63
  • @PaulCrovella I see and understand. I just hope someone finds a clever way to work around this design limitation. If there is no good answer, I know at least that I don't have to try it and that I have to use a custom data structure. – flori Mar 26 '15 at 10:55

2 Answers2

1

One approach is to create a new class derived from an SPL heap, which upon insert only keeps the top (or bottom, depending on the heap) n items.

A super-basic example might look something like:

class Top100 extends SplMinHeap
{
    protected $limit = 100;
    public function insert($value)
    {
        parent::insert($value);
        while (count($this) > $this->limit) {
            $this->extract();
        }
    }
}

This is discussed further in Tobias Schlitt's 2010 article "Heap, heap, hooray!".

salathe
  • 51,324
  • 12
  • 104
  • 132
  • This has the problem that now you cannot extract the top anymore, unless you take them all, and reverse them. – JayTaph Jun 10 '15 at 07:30
1

The problem is that inside a SPLHeap there is no "bottom". Elements are stored in a tree-like structure. The term "bottom" becomes a bit meaningless, however, there is always a "top" of the tree, and this is exactly what SPLHeap can return.

If you have a small number of items, you might get away with alternative data structures (even simple arrays would suffice). Inserting elements might take a bit extra time (this is where trees are much efficient), but maintaining a top and bottom is cheap again (like the SplDoubleLinkedList).

Unless you are storing tens of thousands of elements, you might want to skip the SplHeap for this.

Note: it's trivial enough to create a fixedHeap structure in PHP itself, but i reckon it would not be faster. Benchmark to check what satisfies your needs.

JayTaph
  • 2,846
  • 1
  • 22
  • 29