Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions codes/kotlin/chapter_hashing/array_hash_map.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* File: array_hash_map.kt
* Created Time: 2024-01-25
* Author: curtishd ([email protected])
*/

package chapter_hashing

/* 键值对 */
class Pair(
var key: Int,
var value: String
)

/* 基于数组实现的哈希表 */
class ArrayHashMap {
private val buckets = arrayOfNulls<Pair>(100)

/* 构造方法 */
init {
// 初始化数组,包含 100 个桶
for (i in 0..<100) {
buckets[i] = null
}
}

/* 哈希函数 */
fun hashFunc(key: Int): Int {
val index = key % 100
return index
}

/* 查询操作 */
fun get(key: Int): String? {
val index = hashFunc(key)
val pair = buckets[index] ?: return null
return pair.value
}

/* 添加操作 */
fun put(key: Int, value: String) {
val pair = Pair(key, value)
val index = hashFunc(key)
buckets[index] = pair
}

/* 删除操作 */
fun remove(key: Int) {
val index = hashFunc(key)
// 置为 null ,代表删除
buckets[index] = null
}

/* 获取所有键值对 */
fun pairSet(): MutableList<Pair> {
val pairSet = ArrayList<Pair>()
for (pair in buckets) {
if (pair != null) pairSet.add(pair)
}
return pairSet
}

/* 获取所有键 */
fun keySet(): MutableList<Int> {
val keySet = ArrayList<Int>()
for (pair in buckets) {
if (pair != null) keySet.add(pair.key)
}
return keySet
}

/* 获取所有值 */
fun valueSet(): MutableList<String> {
val valueSet = ArrayList<String>()
for (pair in buckets) {
pair?.let { valueSet.add(it.value) }
}
return valueSet
}

/* 打印哈希表 */
fun print() {
for (kv in pairSet()) {
val key = kv.key
val value = kv.value
println("${key}->${value}")
}
}
}

/* Driver Code */
fun main() {
/* 初始化哈希表 */
val map = ArrayHashMap()

/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.put(12836, "小哈")
map.put(15937, "小啰")
map.put(16750, "小算")
map.put(13276, "小法")
map.put(10583, "小鸭")
println("\n添加完成后,哈希表为\nKey -> Value")
map.print()

/* 查询操作 */
// 向哈希表中输入键 key ,得到值 value
val name: String? = map.get(15937)
println("\n输入学号 15937 ,查询到姓名 $name")

/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.remove(10583)
println("\n删除 10583 后,哈希表为\nKey -> Value")
map.print()

/* 遍历哈希表 */
println("\n遍历键值对 Key->Value")
for (kv in map.pairSet()) {
println("${kv.key} -> ${kv.value}")
}
println("\n单独遍历键 Key")
for (key in map.keySet()) {
println(key)
}
println("\n单独遍历值 Value")
for (value in map.valueSet()) {
println(value)
}
}
36 changes: 36 additions & 0 deletions codes/kotlin/chapter_hashing/built_in_hash.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* File: built_in_hash.kt
* Created Time: 2024-01-25
* Author: curtishd ([email protected])
*/

package chapter_hashing

import utils.ListNode

/* Driver Code */
fun main() {
val num = 3
val hashNum = Integer.hashCode(num)
println("整数 $num 的哈希值为 $hashNum")

val bol = true
val hashBol = Boolean.hashCode()
println("布尔量 $bol 的哈希值为 $hashBol")

val dec = 3.14159
val hashDec = java.lang.Double.hashCode(dec)
println("小数 $dec 的哈希值为 $hashDec")

val str = "Hello 算法"
val hashStr = str.hashCode()
println("字符串 $str 的哈希值为 $hashStr")

val arr = arrayOf<Any>(12836, "小哈")
val hashTup = arr.contentHashCode()
println("数组 ${arr.contentToString()} 的哈希值为 ${hashTup}")

val obj = ListNode(0)
val hashObj = obj.hashCode()
println("节点对象 $obj 的哈希值为 $hashObj")
}
50 changes: 50 additions & 0 deletions codes/kotlin/chapter_hashing/hash_map.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* File: hash_map.kt
* Created Time: 2024-01-25
* Author: curtishd ([email protected])
*/

package chapter_hashing

import utils.printHashMap

/* Driver Code */
fun main() {
/* 初始化哈希表 */
val map: MutableMap<Int, String> = HashMap()

/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map[12836] = "小哈"
map[15937] = "小啰"
map[16750] = "小算"
map[13276] = "小法"
map[10583] = "小鸭"
println("\n添加完成后,哈希表为\nKey -> Value")
printHashMap(map)

/* 查询操作 */
// 向哈希表中输入键 key ,得到值 value
val name = map[15937]
println("\n输入学号 15937 ,查询到姓名 $name")

/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.remove(10583)
println("\n删除 10583 后,哈希表为\nKey -> Value")
printHashMap(map)

/* 遍历哈希表 */
println("\n遍历键值对 Key->Value")
for ((key, value) in map) {
println("$key -> $value")
}
println("\n单独遍历键 Key")
for (key in map.keys) {
println(key)
}
println("\n单独遍历值 Value")
for (value in map.values) {
println(value)
}
}
145 changes: 145 additions & 0 deletions codes/kotlin/chapter_hashing/hash_map_chaining.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* File: hash_map_chaining.kt
* Created Time: 2024-01-25
* Author: curtishd ([email protected])
*/

package chapter_hashing

/* 链式地址哈希表 */
class HashMapChaining() {
var size: Int // 键值对数量
var capacity: Int // 哈希表容量
val loadThres: Double // 触发扩容的负载因子阈值
val extendRatio: Int // 扩容倍数
var buckets: MutableList<MutableList<Pair>> // 桶数组

/* 构造方法 */
init {
size = 0
capacity = 4
loadThres = 2.0 / 3.0
extendRatio = 2
buckets = ArrayList(capacity)
for (i in 0..<capacity) {
buckets.add(mutableListOf())
}
}

/* 哈希函数 */
fun hashFunc(key: Int): Int {
return key % capacity
}

/* 负载因子 */
fun loadFactor(): Double {
return (size / capacity).toDouble()
}

/* 查询操作 */
fun get(key: Int): String? {
val index = hashFunc(key)
val bucket = buckets[index]
// 遍历桶,若找到 key ,则返回对应 val
for (pair in bucket) {
if (pair.key == key) return pair.value
}
// 若未找到 key ,则返回 null
return null
}

/* 添加操作 */
fun put(key: Int, value: String) {
// 当负载因子超过阈值时,执行扩容
if (loadFactor() > loadThres) {
extend()
}
val index = hashFunc(key)
val bucket = buckets[index]
// 遍历桶,若遇到指定 key ,则更新对应 val 并返回
for (pair in bucket) {
if (pair.key == key) {
pair.value = value
return
}
}
// 若无该 key ,则将键值对添加至尾部
val pair = Pair(key, value)
bucket.add(pair)
size++
}

/* 删除操作 */
fun remove(key: Int) {
val index = hashFunc(key)
val bucket = buckets[index]
// 遍历桶,从中删除键值对
for (pair in bucket) {
if (pair.key == key) {
bucket.remove(pair)
size--
break
}
}
}

/* 扩容哈希表 */
fun extend() {
// 暂存原哈希表
val bucketsTmp = buckets
// 初始化扩容后的新哈希表
capacity *= extendRatio
// mutablelist 无固定大小
buckets = mutableListOf()
for (i in 0..<capacity) {
buckets.add(mutableListOf())
}
size = 0
// 将键值对从原哈希表搬运至新哈希表
for (bucket in bucketsTmp) {
for (pair in bucket) {
put(pair.key, pair.value)
}
}
}

/* 打印哈希表 */
fun print() {
for (bucket in buckets) {
val res = mutableListOf<String>()
for (pair in bucket) {
val k = pair.key
val v = pair.value
res.add("$k -> $v")
}
println(res)
}
}
}

/* Driver Code */
fun main() {
/* 初始化哈希表 */
val map = HashMapChaining()

/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.put(12836, "小哈")
map.put(15937, "小啰")
map.put(16750, "小算")
map.put(13276, "小法")
map.put(10583, "小鸭")
println("\n添加完成后,哈希表为\nKey -> Value")
map.print()

/* 查询操作 */
// 向哈希表中输入键 key ,得到值 value
val name = map.get(13276)
println("\n输入学号 13276 ,查询到姓名 $name")

/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.remove(12836)
println("\n删除 12836 后,哈希表为\nKey -> Value")
map.print()
}
Loading