参考的是《数据结构(C语言版)》上256页左右的哈希表的介绍,用了最简单的直接寻址法 + 链地址法。
用的是Kotlin。
package main.kotlin
/**
* 手动实现简单的hash表
* 简单的数组 +链表 (无红黑树)
* 要求哈希函数可配置(被自我否决,太复杂了啦),这次就先做比较简单的 直接定址法 + 链地址法
*
* @Date 2021-10-16.
* @author Johnathan Lin
*/
data class Node(
val key: Int, //key
var value: Int, //value
var next: Node? //如果hash值重复了,则用头插法放进去
)
fun main() {
// hash表,这次可为空
val size = 100
val hashArr: Array<Node?> = Array(size) { null }
//插入 假设插入key 8 value 24
println("插入key 8 value 24")
set(hashArr, size, 8, 24) { k, s -> k % s }
println("插入key 108 value 32")
set(hashArr, size, 108, 32) { k, s -> k % s }
var v = get(hashArr, size, 108) { k, s -> k % s }
println("读取key为108: $v")
println("删除key 108")
remove(hashArr, size, 108) { k, s -> k % s }
v = get(hashArr, size, 108) { k, s -> k % s }
println("读取key为108: $v")
v = get(hashArr, size, 8) { k, s -> k % s }
println("读取key为8: $v")
}
/**
* @param hashFunc 哈希函数 param1:key param2:size
*/
fun get(hashArr: Array<Node?>, size: Int, key: Int, hashFunc: (Int, Int) -> Int): Node? {
val pos = hashFunc.invoke(key, size)
val queueHead = hashArr[pos]
if (queueHead == null) {
return null
} else {
if (queueHead.key == key) {
return queueHead
}
var p = queueHead
while(p?.next != null) {
if (p.next?.key == key) {
return p.next
}
p = p.next
}
}
return null
}
fun set(hashArr: Array<Node?>, size: Int, key: Int, value: Int, hashFunc: (Int, Int) -> (Int)) {
//get 不到的时候才会set
val node = get(hashArr, size, key, hashFunc)
if (node != null) {
node.value = value
} else {
val pos = hashFunc.invoke(key, size)
val newNode = Node(key, value, null)
if (hashArr[pos] == null) {
hashArr[pos] = newNode
} else {
val next = hashArr[pos]?.next
if (next == null) {
hashArr[pos]?.next = newNode
} else {
newNode.next = next
hashArr[pos]?.next = newNode
}
}
}
}
fun remove(hashArr: Array<Node?>, size: Int, key: Int, hashFunc: (Int, Int) -> (Int)) {
val pos = hashFunc.invoke(key, size)
val queueHead = hashArr[pos]
if (queueHead == null) {
return
} else {
if (queueHead.key == key) {
if (queueHead.next != null) { //好像jdk7有一个hashMap的bug?
hashArr[pos] = queueHead.next
return
} else {
hashArr[pos] = null
}
} else {
var p = queueHead
while(p?.next != null) {
if (p.next?.key == key) {
if (p.next?.next != null) {
p.next = p.next?.next
} else {
p.next = null
}
return
}
p = p.next
}
}
}
}
然后是输出:
插入key 8 value 24
插入key 108 value 32
读取key为108: Node(key=108, value=32, next=null)
删除key 108
读取key为108: null
读取key为8: Node(key=8, value=24, next=null)
Process finished with exit code 0