-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash_table_open_addressing.py
131 lines (112 loc) · 3.41 KB
/
hash_table_open_addressing.py
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
126
127
128
129
130
131
ENTRY_EMPTY = 0
ENTRY_DUMMY = 1
ENTRY_NORMAL = 2
def get_status(s):
m = {
ENTRY_EMPTY: 'ENTRY_EMPTY',
ENTRY_DUMMY: 'ENTRY_DUMMY',
ENTRY_NORMAL: 'ENTRY_NORMAL'
}
return m.get(s)
class Entry:
def __init__(self, key, value):
self.key = key
self.value = value
self.status = ENTRY_EMPTY
class HashTable:
def __init__(self, size):
self.size = size
self.table = []
for i in range(self.size):
self.table.append(Entry(None, None))
def _find(self, key):
index = self._hash(key)
i = 1
print('index: ', end='')
while self.table[index].status != ENTRY_EMPTY and self.table[index].key != key:
print(index, end=' ')
index += 2 * i - 1
index %= self.size
i += 1
print(index)
return index
def find(self, key):
index = self._find(key)
entry = self.table[index]
if entry.status == ENTRY_NORMAL:
return entry.value
return None
def insert(self, key, value):
index = self._find(key)
entry = self.table[index]
entry.key = key
entry.status = ENTRY_NORMAL
entry.value = value
def delete(self, key):
index = self._find(key)
entry = self.table[index]
if entry.status == ENTRY_EMPTY or entry.status == ENTRY_DUMMY:
raise Exception('{} not exists'.format(key))
entry.status = ENTRY_DUMMY
return entry.value
def _hash(self, key):
# return hash(key)
if isinstance(key, int):
return key % self.size
elif isinstance(key, str):
h = 0
for c in key:
h = (h << 5) + c
return h % self.size
return hash(key) % self.size
def __str__(self):
s = ''
for i, entry in enumerate(self.table):
s += '{i} -> [{k}: {v}] {s}\n'.format(i=i, k=entry.key, v=entry.value, s=get_status(entry.status))
return s
class HashTable2(HashTable):
def _find(self, key):
index = self._hash(key)
i = 1
while self.table[index].status != ENTRY_EMPTY:
entry = self.table[index]
if entry.status == ENTRY_NORMAL and entry.key == key:
break
index += 2 * i - 1
i += 1
return index
def insert(self, key, value):
index = self._hash(key)
i = 1
first_dummy = None
entry = self.table[index]
while entry.status != ENTRY_EMPTY:
if first_dummy is None and entry.status == ENTRY_DUMMY:
first_dummy = entry
if entry.status == ENTRY_NORMAL and entry.key == key:
break
index += 2 * i - 1
i += 1
entry = self.table[index]
if entry.status == ENTRY_EMPTY and first_dummy is not None:
entry = first_dummy
entry.key = key
entry.value = value
entry.status = ENTRY_NORMAL
if __name__ == '__main__':
import random
h = HashTable2(10)
# for i in range(5):
# k = random.randint(1, 100)
# v = int(random.random() * 10)
# print('insert {} {}'.format(k, v))
# h.insert(k, v)
# print(h)
h.insert(1, 2)
h.insert(11, 3)
h.delete(1)
print(h)
h.insert(11, 5)
print(h)
h.insert(1, 10)
print(h)