From 226fc3969f62d13aca63f2deb983fab6d14fac8d Mon Sep 17 00:00:00 2001 From: Cielfe Date: Thu, 11 Jun 2026 22:20:13 +0900 Subject: [PATCH 1/2] Add binary heap (min-heap) implementation in R --- data_structures/binary_heap.r | 106 ++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 data_structures/binary_heap.r diff --git a/data_structures/binary_heap.r b/data_structures/binary_heap.r new file mode 100755 index 0000000..0a4a699 --- /dev/null +++ b/data_structures/binary_heap.r @@ -0,0 +1,106 @@ +# A binary heap is a complete binary tree where each node is smaller than or +# equal to its children (min-heap). The minimum is always at the root. +# +# To insert a value, add it as the last node and swap it upward +# until the heap property holds (sift up). +# +# To remove the minimum, move the last node to the root and swap it +# downward until the heap property holds (sift down). +# +# Time Complexities: +# - Push (insert): O(log n) +# - Pop (extract min): O(log n) +# - Peek: O(1) +# +# Space Complexity: O(n) +# +# Applications: +# - Priority queues (task scheduling, process management) +# - Dijkstra's shortest path algorithm +# - Heap sort +# - Finding the k smallest/largest elements (Top-K) +# - Event-driven simulation +# +# Example usage: +# h <- c() # create an empty heap +# h <- push(h, 5) # insert values +# h <- push(h, 3) +# h <- push(h, 8) +# peek(h) # view the minimum (3) without removing +# res <- pop(h) # extract the minimum +# res$value # -> 3 (the minimum that was removed) +# res$heap # -> the heap after removal + + +push <- function(heap, value) { + + heap <- c(heap, value) + i <- length(heap) + + while (i > 1) { + + p <- i %/% 2 + + if (heap[p] > heap[i]){ + heap[c(p, i)] <- heap[c(i, p)] + i <- p + } + else { + break + } + } + return(heap) +} + +pop <- function(heap) { + + min_value <- heap[1] + + heap[1] <- heap[length(heap)] + heap <- heap[-length(heap)] + + i <- 1 + child <- 0 + + while (2 * i <= length(heap)){ + if ((2 * i + 1 <= length(heap) && heap[2 * i + 1] < heap[2 * i])){ + child <- 2 * i + 1 + } + else { + child <- 2 * i + } + + if (heap[child] < heap[i]){ + heap[c(child, i)] <- heap[c(i, child)] + i <- child + } + else { + break + } + } + + return(list(value = min_value, heap = heap)) +} + +peek <- function(heap) { + return(heap[1]) +} + +# Test + +h <- c() +h <- push(h, 5) +h <- push(h, 3) +h <- push(h, 8) +h <- push(h, 1) +h <- push(h, 9) +h <- push(h, 2) + +print(peek(h)) +print(h) + +res <- pop(h) +print(res$value) +print(res$heap) + + From a1c622360d0e95b7fd75b873e243beee4c852718 Mon Sep 17 00:00:00 2001 From: Cielfe Date: Fri, 12 Jun 2026 11:12:07 +0900 Subject: [PATCH 2/2] Add empty-heap guards and guard demo block in binary heap --- data_structures/binary_heap.r | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/data_structures/binary_heap.r b/data_structures/binary_heap.r index 0a4a699..2b2a7cd 100755 --- a/data_structures/binary_heap.r +++ b/data_structures/binary_heap.r @@ -53,6 +53,9 @@ push <- function(heap, value) { } pop <- function(heap) { + if (length(heap) == 0){ + stop("Heap underflow: cannot pop from an empty heap") + } min_value <- heap[1] @@ -83,24 +86,28 @@ pop <- function(heap) { } peek <- function(heap) { + if (length(heap) == 0){ + stop("Heap underflow: cannot peek") + } return(heap[1]) } # Test +if (sys.nframe() == 0){ + h <- c() + h <- push(h, 5) + h <- push(h, 3) + h <- push(h, 8) + h <- push(h, 1) + h <- push(h, 9) + h <- push(h, 2) -h <- c() -h <- push(h, 5) -h <- push(h, 3) -h <- push(h, 8) -h <- push(h, 1) -h <- push(h, 9) -h <- push(h, 2) + print(peek(h)) + print(h) -print(peek(h)) -print(h) - -res <- pop(h) -print(res$value) -print(res$heap) + res <- pop(h) + print(res$value) + print(res$heap) +}