Skip to content

Instantly share code, notes, and snippets.

@lemnik
Created April 29, 2020 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lemnik/691b2d56373c11b8de41dc516bfe54a9 to your computer and use it in GitHub Desktop.
Save lemnik/691b2d56373c11b8de41dc516bfe54a9 to your computer and use it in GitHub Desktop.
Simple HuffmanTree / HuffmanTable implementation in Kotlin
import java.util.*
class HuffmanTree<T> {
private val root: Node<T>
constructor(vararg elements: Node<T>) : this(elements.toList())
constructor(elements: Collection<Node<T>>) {
val queue = PriorityQueue(elements)
while (queue.size > 1) {
val left = queue.remove()
val right = queue.remove()
queue.add(Node(left.frequency + right.frequency, null, left, right))
}
root = queue.poll()!!
}
fun writeValue(value: T, writeBit: (Boolean) -> Unit) = root.write(value, writeBit)
fun readValue(readBit: () -> Boolean) = root.read(readBit)
data class Node<T> internal constructor(
val frequency: Int,
val value: T?,
val left: Node<T>? = null,
val right: Node<T>? = null
) : Comparable<Node<T>> {
/**
* Create a new tree Node with a specified frequency and value. Use this constructor
* when passing Node objects to a HuffmanTrees.
*/
constructor(frequency: Int, value: T) : this(frequency, value, null, null)
override fun compareTo(other: Node<T>): Int = frequency - other.frequency
internal fun contains(v: T): Boolean =
if (left != null && right != null) left.contains(v) || right.contains(v)
else value == v
internal fun write(v: T, writeBit: (Boolean) -> Unit) {
when {
left?.contains(v) == true -> {
writeBit(false)
left.write(v, writeBit)
}
right?.contains(v) == true -> {
writeBit(true)
right.write(v, writeBit)
}
v != value -> throw IllegalArgumentException("Unknown value: $v")
}
}
fun read(readBit: () -> Boolean): T =
value ?: if (readBit()) right!!.read(readBit) else left!!.read(readBit)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment