From b1889cbbbaaf10c82b52994002569de72163d4d3 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 4 Dec 2020 23:24:41 -0800 Subject: [PATCH] Add heap. --- heap.cr | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 heap.cr diff --git a/heap.cr b/heap.cr new file mode 100644 index 0000000..cc106b9 --- /dev/null +++ b/heap.cr @@ -0,0 +1,83 @@ +class Array(T) + def bubble_up(i, &cmp) + return if i >= size + while i != 0 + j = (i-1)//2 + break if yield self[i], self[j] + self[i], self[j] = self[j], self[i] + i = j + end + end + + def percalate_down(i, &cmp) + while i*2+1 < size + j1, j2 = i*2+1, i*2+2 + v1 = self[j1] + v2 = self[j2]? + if v2 && (yield v1, v2) && (yield self[i], v2) + self[j2], self[i] = self[i], v2 + i = j2 + elsif yield self[i], v1 + self[j1], self[i] = self[i], v1 + i = j1 + else + break + end + end + end + + def heapify(&cmp : T,T -> Bool) + size.times do |i| + i = size - i - 1 + bubble_up(i, &cmp) + end + self + end + + def heapify + heapify do |i,j| + i < j + end + end + + def heap_push(v, &cmp : T,T -> Bool) + self << v + bubble_up(size - 1, &cmp) + end + + def heap_push(v) + heap_push(v) do |i,j| + i < j + end + end + + def heap_pop(&cmp : T,T -> Bool) + self[0], self[size-1] = self[size-1], self[0] + v = pop + percalate_down(0, &cmp) + v + end + + def heap_pop + heap_pop do |i, j| + i < j + end + end + + def is_heap?(&cmp : T,T -> Bool) + (size-1).times do |i| + i = size - i - 1 + vi = self[i] + vp = self[(i-1)//2] + return false unless (yield self[i], self[(i-1)//2]) || vi == vp + end + return true + end + + def is_heap? + is_heap? do |i,j| + i < j + end + end + +end