0.0
No commit activity in last 3 years
No release in over 3 years
Implementation of a binary heap in Ruby. See github for usage examples.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

Implementation of a binary heap in Ruby.

Gem is published at: https://rubygems.org/gems/rb_binary_heap

require 'rb_binary_heap'

# This array will be used in the examples below
array = [1, 3, 0, 8]

# Initialize min heap from array
min_heap = BinaryHeap.new(array.dup) 
# the same as BinaryHeap.new(array.dup, type: :min)

min_heap.each do |n|
  p n # prints 0, 1, 3, 8
end
# min_heap is now empty, iteration over heap pops its elements

# Initialize max heap from array
max_heap = BinaryHeap.new(array.dup, type: :max)

while max_heap.not_empty? do
  n = max_heap.pop
  p n # prints 8, 3, 1, 0
end

# Heap :type can be either :min or :max, 
# min compares elements with :<, popped elements will be in increasing order,
# max compares elements with :>, popped elements will be in decreasing order

# Also you can create an empty heap and push elements onto it

min_heap = BinaryHeap.new # the same as BinaryHeap.new(type: :min)

# push elements 
array.each do |n|
  min_heap.push n
end
# or like this
min_heap = array.inject(BinaryHeap.new) { |heap, n| heap.push n } 

# What if you need custom comparison for elements?
# For example, you want to create a heap of strings
# and it should be ordered by decreasing string size.
# For cases like this, you can use a block

custom_heap = BinaryHeap.new { |a, b| a.size > b.size }
# which also can be written like this
# custom_heap = BinaryHeap.new(type: :max, compare_attribute: :size)

# push calls can be chained
custom_heap.push("aa").push("aaa").push("a")

custom_heap.each do |s|
  p s # prints "aaa", "aa", "a"
end

# You can get a sorted array from heap with to_a
min_heap = BinaryHeap.new(array.dup)

p min_heap.to_a # prints 0, 1, 3, 8
# min_heap is now empty

# In all the examples above, where the heap was created from array,
# array.dup was used in heap initialization, like this:
# min_heap = BinaryHeap.new(array.dup)
# Because heap modifies the array passed to it, dup is used
# to copy the original array to prevent its modification.
# But if you don't care if original array is modified or not,
# you don't have to copy it with dup before passing it to Heap:

# Let Heap use the array, without copying it
min_heap = BinaryHeap.new(array) 

min_heap.each do |n|
  p n # prints 0, 1, 3, 8
end
# Both min_heap and array are now empty

# As a final example, let's solve a LeetCode problem 'Merge K sorted lists'
# https://leetcode.com/problems/merge-k-sorted-lists/description/

def merge_k_lists(lists)
  lists = lists.reject(&:nil?)
  heap = BinaryHeap.new(lists, compare_attribute: :val)
  # also can be equivalently defined like this
  # heap = BinaryHeap.new(lists) { |a, b| a.val < b.val }
  head, last = nil, nil
  while heap.not_empty?
    current = heap.pop
    if head.nil?
      head, last = current, current
    else
      last.next = current
      last = current
    end
    heap.push(current.next) if current.next
    last.next = nil
  end
  head
end