-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHashTable.swift
125 lines (80 loc) · 3.21 KB
/
HashTable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// HashTable.swift
// SwiftStructures
//
// Created by Wayne Bishop on 7/5/16.
// Copyright © 2016 Arbutus Software Inc. All rights reserved.
//
import Foundation
/*
note: a generic hash table. types supported must conform to the
custom Keyable protocol.
*/
class HashTable<T: Keyable> {
private var buckets: Array<Node<T>?>
/*
note: initializing the hash table with an initial capacity shown
for educational purposes only.
*/
init(capacity: Int) {
self.buckets = Array<Node<T>?>(repeatElement(nil, count: capacity))
}
//TODO: create a computed property - hashvalue that calculates the key for a specific index.
//add item to list
func insert(_ element: T) -> Result {
let result: Result
//compute hash
let hashIndex = element.hashValue(for: element.keystring, using: buckets)
if hashIndex != -1 {
let childToUse = Node<T>()
childToUse.key = element
//check existing list
if buckets[hashIndex] == nil {
buckets[hashIndex] = childToUse
result = Result.Success
}
else {
print("collision occurred. implementing chaining..")
var head = buckets[hashIndex] as Node<T>?
//append item
childToUse.next = head
head = childToUse
//update chained list
buckets[hashIndex] = head
result = Result.Collision
}
}
else {
result = Result.Fail
}
return result
}
//test for containing element
func contains<T: Keyable>(_ element: T) -> Bool {
//obtain hash index
let hashIndex = element.hashValue(for: element.keystring, using: buckets)
guard hashIndex != -1 else {
return false
}
if buckets[hashIndex] != nil {
var current = buckets[hashIndex]
//check chained list for match
while current != nil {
/*
note: test for equality. since the user provided input as well as
the hash table contents both conform to the Keyable protocol, table
elements can be interpreted as a Keyable "type". This centralized
conformance allows seemingly different objects to
be compared equally (e.g. String vs Vertex).
*/
if let item: Keyable = current?.key {
if item.keystring == element.keystring {
return true
}
}
current = current?.next
} //end while
}
return false
}
}