Skip to content

Instantly share code, notes, and snippets.

@davidinga
Last active June 17, 2019 20:15
Show Gist options
  • Save davidinga/ee9d26b390e192e6d691d86299503bf8 to your computer and use it in GitHub Desktop.
Save davidinga/ee9d26b390e192e6d691d86299503bf8 to your computer and use it in GitHub Desktop.
Hash Table with Chaining. Chaining implemented with Linked List.
struct HashTable<Key: Hashable, Value> {
private typealias Element = (key: Key, value: Value)
private typealias List = SinglyLinkedList<Element>
private var table: [List]
private(set) public var count = 0
var isEmpty: Bool {
return count == 0
}
init(size: Int) {
assert(size > 0)
table = Array<List>()
for _ in 0..<size {
let list = List()
table += [list]
}
}
subscript(key: Key) -> Value? {
get {
return value(forKey: key)
}
set {
if let value = newValue {
updateValue(value, forKey: key)
} else {
removeValue(forKey: key)
}
}
}
func value(forKey key: Key) -> Value? {
let index = self.index(forKey: key)
var node = table[index].first
while node != nil {
if node!.element.key == key {
return node!.element.value
}
node = node!.next
}
return nil
}
@discardableResult mutating func updateValue(_ value: Value, forKey key: Key) -> Value? {
let index = self.index(forKey: key)
var node = table[index].first
while node != nil {
if node!.element.key == key {
let oldValue = node!.element.value
node!.element.value = value
return oldValue
}
node = node!.next
}
table[index].append((key: key, value: value))
count += 1
return nil
}
@discardableResult mutating func removeValue(forKey key: Key) -> Value? {
let index = self.index(forKey: key)
var node = table[index].first
while node != nil {
if node!.element.key == key {
count -= 1
return table[index].remove(node: node!)!.element.value
}
node = node!.next
}
return nil
}
mutating func removeAll() {
table = Array<List>(repeatElement(List(), count: table.count))
count = 0
}
func index(forKey key: Key) -> Int {
return abs(key.hashValue % table.count)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment