views:

182

answers:

2

I need a datastructure in Ruby that keeps its elements sorted as elements are added or deleted and allows (at least) the ability to pop the first element off the list.

The closest thing I've found in the ruby docs is SortedSet. However, this doesn't seem to provide any way to access the elements by their index (or even pop the first element off)

These are the specific operations I need:

  • Add object to the list
  • Pop first object off of the list
  • Check if an object is in the list
  • Remove object from the list (by object, not by index)

Does ruby have anything built in for this, or are there any libraries I can grab that would give it to me? I could implement one without too much difficulty but I'd rather use a preexisting one if possible.

Currently I'm using Ruby 1.8, though switching to 1.9 would probably be ok.

EDIT:

Since there seems to be some confusion, the sorting I need isn't the order that the objects are inserted. I need the sorting to be based on the <=> operator. Generally I'll be popping the first element, processing that (which may generate new elements), adding new elements to the list, then repeating. The elements being added could end up anywhere in the sorting order, not just at the end.

+2  A: 

may want to condiser this 1.8-compatible gem for red black trees which does this (Ruby/RBTree):

http://www.geocities.co.jp/SiliconValley-PaloAlto/3388/rbtree/README.html

tree is always kept balanced, operations on the tree are O(log N)

there's also a red black tree implementation here:

http://github.com/kanwei/algorithms

Containers::RubyRBTreeMap

jspcal
Hadn't thought to look for a tree structure (though it seems kind of obvious now that I think about it). That looks perfect.
Herms
Have you used either of those? Any idea if one is better than the other?
Herms
have used the first, the 2nd is newer, looks very nice as well
jspcal
2nd looks nice in general, but the 1st's API is a little nicer (includes shift/unshift). It looked like the 2nd's Heap class would be good, but I'm quite getting the sorting to work properly. I'll play with both of them.
Herms
Note that there is a reasonable chance that RBTree makes it into the standard ruby lib (see http://redmine.ruby-lang.org/issues/show/2348 )
Marc-André Lafortune
Ended up creating a simple wrapper class on RBTree for a queue: http://blog.aherrman.com/2010/01/sortedqueue-in-ruby.html
Herms
+1  A: 

Although inefficient (if you use it often), SortedSet has a to_a method that you can use to access the items:

s = SortedSet.new
s << 1
s << 0
s << 3
puts s.to_a[0] # => 0
Theo
That works, but would be incredibly inefficient for what I'm doing (lots of changes between accesses)
Herms