HiveBrain v1.2.0
Get Started
← Back to all entries
patternkotlinMinor

Max heap implementation in Kotlin

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationmaxkotlinheap

Problem

I wrote this class a while ago to learn Kotlin and heaps, so any tips (on either my code style or my heap algorithm) would be appreciated!

```
class MaxHeap>() {
private val items: MutableList = mutableListOf()
var size: Int = 0
private set

fun push(item: T) {
set(size++, item)
siftUp(size - 1)
}

fun peek() = get(0)

fun pop(): T? {
// If there are no items in the heap, null is returned
if (size == 0) {
return null
}

// Get the max item, replace it with the last item in the heap,
// then sift it down until the heap property is restored
val max = peek()
set(0, get(--size))
items.removeAt(size) // Remove original reference to the last item
siftDown(0)
return max
}

private fun siftUp(i: Int) {
assert(i >= 0 && i get(iParent)!!) {
swap(i, iParent)
siftUp(iParent)
}
}

private fun siftDown(i: Int) {
assert(i >= 0 && i = size / 2) {
return
}

// Find the larger child value.
// Left child is guaranteed to exist because this is not a leaf node,
// and because we add items to the heap by appending them to the end,
// the left mode must be filled before the right node.
val iLeft = leftChildIndex(i)
val iRight = rightChildIndex(i)
var iLargerChild = iLeft
if (iRight < size && get(iLeft)!! < get(iRight)!!) {
iLargerChild = iRight
}

// If this item is less than the larger child, sift it down
if (get(i)!! < get(iLargerChild)!!) {
swap(i, iLargerChild)
siftDown(iLargerChild)
}
}

private fun set(i: Int, value: T?) {
if (i < items.size) {
items[i] = value
} else {
items.add(value)
}
}

private fun get(i: Int): T? {
if (i < items.size) {
return

Solution


  • private val items: MutableList = mutableListOf() can be written more succinctly as private val items = mutableListOf() (the type is inferred and then no longer repeated (mostly) in an explicit type definition and the factory method call).



-
size can be backed by items.size:

val size: Int
    get() = items.size

fun push(item: T) {
    set(size + 1, item)
    siftUp(size - 1)
}

...

fun pop(): T? {
    ...
    set(0, get(size - 1))
    items.removeAt(items.lastIndex) // Remove original reference to the last item
    ...
}


  • siftDown throws an AssertionError assertion when size == 0.



-
push and pop have different meanings in the Java Collections Framework associated with using a java.util.Deque as a stack. You might instead use the same verbs as java.util.PriorityQueue (namely add and remove) which can be used as a max heap:

fun > maxHeap() = PriorityQueue(Comparator.reverseOrder())

Code Snippets

val size: Int
    get() = items.size

fun push(item: T) {
    set(size + 1, item)
    siftUp(size - 1)
}

...

fun pop(): T? {
    ...
    set(0, get(size - 1))
    items.removeAt(items.lastIndex) // Remove original reference to the last item
    ...
}
fun <T : Comparable<T>> maxHeap() = PriorityQueue<T>(Comparator.reverseOrder<T>())

Context

StackExchange Code Review Q#122777, answer score: 8

Revisions (0)

No revisions yet.