Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 36 additions & 26 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The DS gem supports the folowing data structures:


== Instalation

gem install ds

== Usage
Expand Down Expand Up @@ -65,7 +65,7 @@ Accessors defined on Pair object:
Stack is very simple data structure which allows access only to the top element.
More: {Stack}[http://en.wikipedia.org/wiki/Stack_(abstract_data_type)]

Creating new Stack (implemented as Array).
Creating new Stack (implemented as Array).
stack = Stack.new

The following methods are available on a Stack:
Expand Down Expand Up @@ -97,7 +97,7 @@ More: {Queue}[http://en.wikipedia.org/wiki/Queue_(data_structure)]

==== Queue

Creating new Queue (implemented as Array).
Creating new Queue (implemented as Array).
q = Queue.new

Creating new Queue (implemented as List)
Expand All @@ -123,14 +123,14 @@ Examples:
q.empty? #=> true


==== Priority Queue
==== Priority Queue

PriorityQueue is special form of Queue (PriorityQueue inherits from Queue).
In opposite to simple Queue, in PriorityQueue each element is associated with a "priority".
More: {Priority Queue}[http://en.wikipedia.org/wiki/Priority_queue]

Creating new Priority Queue (implemented as BinaryHeap)

q = PriorityQueue.new

Examples:
Expand All @@ -144,6 +144,16 @@ Examples:
q.shift #=> :important
q.peek #=> :nevermind

Defining an alternate definition of priority (here, lower number means higher priority):
q = PriorityQueue.new{|a,b| a<b}
q.push(:three, 3)
q.push(:one, 1)
q.shift #=> :one

q = PriorityQueue.new{|a,b| a>b}
q.push(:three, 3)
q.push(:one, 1)
q.shift #=> :three


=== Lists
Expand All @@ -157,15 +167,15 @@ More: {List}[http://en.wikipedia.org/wiki/List_(data_structure)]
Creating new List
l = List.new(1)
l.append(2)
or
or
arr = [1,2,3,4]
list = List.from_array(arr)

Examples:

Simple operation on lists
list.length #=> 4
list.append(5).to_a #=> [1,2,3,4,5]
list.append(5).to_a #=> [1,2,3,4,5]
list.prepend(0).to_a #=> [0,1,2,3,4,5]
list.remove(list.head).to_a #=> [1,2,3,4,5]
list.shift #=> 1
Expand All @@ -181,7 +191,7 @@ Reversing
list.reverse!.to_a #=> [5,4,3,1,0]

Enumerable methods are also available

list.map{ |e| e.data } #=> [1,2,3,4]
list.inject(0){ |mem, var| mem = mem + var.data } #=> 10

Expand All @@ -204,14 +214,14 @@ Examples:
ring.looped? #=> true
ring.cycle_size #=> 7
ring.eliminate_by(2) #=> 1



=== Trees

==== Tree

A tree is a data structure consisting of nodes organised as a hierarchy.
A tree is a data structure consisting of nodes organised as a hierarchy.
More: {Tree}[http://en.wikipedia.org/wiki/Tree_(data_structure)]

Building Tree
Expand All @@ -232,8 +242,8 @@ Examples:
t.height #=> 3
t.width #=> 3
t.leaf_count #=> 4
t.levels #=> {1=>1,2=>3, 3=>3}

t.levels #=> {1=>1,2=>3, 3=>3}

Other methods
* get_leaves
Expand Down Expand Up @@ -276,7 +286,7 @@ Examples
==== CompleteBinaryTree

A complete binary tree is a binary tree in which every level, except possibly
the last, is completely filled, and all nodes are as far left as possible.
the last, is completely filled, and all nodes are as far left as possible.
CompleteBinaryTree is binary tree but does not inherit from Tree and BinaryTree class! Nodes are stored
internally in array.
More: {Complete Binary Tree}[http://en.wikipedia.org/wiki/Complete_binary_tree]
Expand All @@ -289,7 +299,7 @@ Examples
cbt.left(0) #=> 2
cbt.right(0) #=> 3
cbt.parent(1) #=> 0

cbt.left_index(0) #=> 1
cbt.right_index(1) #=> 4
cpt.parent_index(1) #=> 0
Expand All @@ -303,7 +313,7 @@ More: {Binary Heap}[http://en.wikipedia.org/wiki/Binary_heap]

Creating

Maximum Binary Heap
Maximum Binary Heap
max_heap = BinaryHeap.new(9,8,4,5,11,6)
or
max_heap = BinaryHeap.max(9,8,4,5,11,6)
Expand All @@ -324,30 +334,30 @@ Examples
min_heap.shift #returns min element (4)


==== Trie
==== Trie

Trie is an ordered tree data structure which allows very quick search: O(k), where k is word length.
More: {Trie}[http://en.wikipedia.org/wiki/Trie]

Creating
Creating
trie = Trie.new

Examples
trie.insert("thing",true);
trie.find("thing") # => true


==== Traversing Tree
==== Traversing Tree

b= BinaryTree.new
[2,5,8,9,11,12,14].each{|x| b.insert(x)}
[2,5,8,9,11,12,14].each{|x| b.insert(x)}

walker = TreeWalker.new(b)

Iterating in postorder
Iterating in postorder
walker.traverse(:postorder) #=> [9,11,5,12,14,8,2]
Iterating in inorder
walker.traverse(:inorder) #=> [9,5,11,2,12,8,14]
walker.traverse(:inorder) #=> [9,5,11,2,12,8,14]
Iterating in preorder
walker.traverse(:preorder) #=> [2,5,9,11,8,12,14]

Expand All @@ -359,7 +369,7 @@ You can also pass block to traverse method
walker.traverse(:inorder){|n| p n.data**2}

If you want to change value of tree nodes, use recalculate! method
walker.recalculate!(b,:preorder,0){|x,memo| memo = memo+x.data}
walker.recalculate!(b,:preorder,0){|x,memo| memo = memo+x.data}



Expand All @@ -374,7 +384,7 @@ More: {Graph}[http://en.wikipedia.org/wiki/Graph_(data_structure)]
====Graph

Creating new Graph

edges = []
edges << Edge.new('Lukas','Marc')
edges << Edge.new('Lukas','Tom')
Expand Down Expand Up @@ -406,7 +416,7 @@ Iterating
==== Digraph

Creating Directed Weighted Graph is simple like that:

edges = []

edges << Edge.new(:A,:C,5)
Expand Down Expand Up @@ -438,7 +448,7 @@ Examples

==== Array2D

Simple two dimensional array(matrix).
Simple two dimensional array(matrix).
Array2D extends automatically like simple Array.

Creating
Expand Down
29 changes: 26 additions & 3 deletions lib/ds/queues/priority_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,31 @@ module DS
class PriorityQueue < Queue

#Create new priority queue. Internaly uses heap to store elements.
#
# The definition of priority can be defined in a block given to this constructor.
# Not providing a block is equivalent to providing the following block (higher
# numbers mean more priority)
#
# DS::PriorityQueue.new{|a,b| a >= b}
#
# Alternately, to provide lower priority
#
# DS::PriorityQueue.new{|a,b| a <= b}
#
# Note that the ordering must be consistent, otherwise strange things may happen.
# For instance the block should not define the following ordering:
#
# rock > scissors
# scissors > paper
# paper > rock
def initialize
@store = BinaryHeap.new {|parent,child| parent.key >= child.key}
if block_given?
@store = BinaryHeap.new do |parent,child|
yield parent.key, child.key
end
else
@store = BinaryHeap.new {|parent,child| parent.key >= child.key}
end
end


Expand All @@ -13,10 +36,10 @@ def enqueue x, priority
@store.insert(pair)
self
end

alias :push :enqueue

#Removes element with highest priority from queue .
#Removes element with highest priority from queue .
def dequeue
if x = @store.shift
x.value
Expand Down
35 changes: 34 additions & 1 deletion test/test_priority_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,45 @@
end
end

describe 'priority queue with alternate ordering' do
before do
@queue = PriorityQueue.new{|a,b| a<b}
@queue.enqueue :important, 1
@queue.enqueue :not_important, 2
end

it "should not be empty." do
refute @queue.empty?
@queue.length.must_equal 2
end

it "#peek should return element with highest priority." do
@queue.peek.must_equal :important
end


it "#enqueue and #push should add element to priority queue." do
@queue.enqueue :very_important, 5
@queue.push :nevermind, 0
@queue.length.must_equal 4
end

it "#dequeue and #shift should remove element with highest priority." do
x = @queue.dequeue
@queue.length.must_equal 1
x.must_equal :important
@queue.dequeue.must_equal :not_important
@queue.length.must_equal 0
@queue.dequeue.must_be_nil
end
end


if ENV['BENCH']
describe "performance" do

before do

@queue = PriorityQueue.new
10000.times do |n|
@queue.push :elem, rand(10)
Expand Down