-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashtable_open_addressing.py
More file actions
161 lines (140 loc) · 5.46 KB
/
hashtable_open_addressing.py
File metadata and controls
161 lines (140 loc) · 5.46 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# HashTable ADT with chaining implementation
# This hashtable accepts only strings and hashes based on their
# ASCII value of the first char
# The constructor takes in the size of the table
## Example hashtable
# class MyHashtable(object):
# def __init__(self, size): # Creates an empty hashtable
# self.size = size
# # Create the list (of size) of empty lists (chaining)
# self.table = []
# for i in range(self.size):
# self.table.append([])
# def str (self): # for print
# return str(self.table)
# def insert(self, elem): # Adds an element into the hashtable
# hash = ord(elem[0]) % self.size
# self.table[hash].append(elem)
# def member(self, elem): # Returns if element exists in hashtable
# hash = ord(elem[0]) % self.size
# return elem in self.table[hash]
# def delete(self, elem): # Removes an element from the hashtable
# hash = ord(elem[0]) % self.size
# self.table[hash].remove(elem)
# Testing code for 'MyHashtable'
# s = MyHashtable(10)
# s.insert("amy") #97
# print(s.str())
# s.insert("chase") #99
# print(s.str())
# s.insert("chris") #99
# print(s.str())
#
# print(s.member("amy"))
# print(s.member("chris"))
# print(s.member("alyssa"))
# s.delete("chase")
# print(s.member("chris"))
# print(s.str())
# Use print(s) at any time to see the contents of the table for debugging
# 'NewHashtable' ADT for Open Addressing w/ Linear Probing
# - Each location in table holds only one value, storing 'None' on __init__
# - Second table will hold the status of each index: 'Empty', 'Filled', or 'Deleted'
# - When insert/delete/find member, use method from 'MyHashtable', ASCII value of first char of str
# - Goal is to insert new member at "next available" spot, searching until finding one that isn't 'Filled'
# - Needs to wrap to start of table w/ a mod when probing.
# - Once spot that isn't 'Filled' encountered, assign new member to it and mark as 'Filled'
# - ASSUME THAT HASHTABLE WILL NEVER FILL UP, DO NOT ACCOUNT FOR THIS
#
# find/delete member are similar:
# - Jump to hashed location, if member there is not desired member, probe down table to find it
# - Search should end if you find desired member, but also if you encounter 'Empty' spot because
# this indicates that desired member DOES NOT EXIST
# - For NewHashtable.member(): simply return T/F
# - For NewHashtable.delete(): if desired member found, set MemberTable value to 'None' and
# StatusTable value to 'Deleted', do not do anything if desired member does not exist
# - Test 'NewHashtable' with the same cases provided for 'MyHashtable'
class NewHashtable(object):
def __init__(self,size):
self.size = size
self.members = [None for i in range(size)]
self.status = ['Empty' for i in range(size)]
def memstr (self): # for print
return str(self.members)
def valstr (self): # for print
return str(self.status)
def insert(self, elem): # Adds an element into the hashtable
# MUST CHECK STATUS TABLE BEFORE APPLYING MEMBER TABLE CHANGES
hash = ord(elem[0]) % self.size
counter = hash # indexing variable for both .members and .status
counter_start = counter
while True:
if counter == self.size:
counter = 0
if self.status[counter] != 'Filled':
self.members[counter] = elem
self.status[counter] = 'Filled'
break
counter += 1
if counter == counter_start:
raise Warning(f"{self} object has no fillable spots: .insert() attempt terminated")
break
def member(self, elem): # Returns if element exists in hashtable
hash = ord(elem[0]) % self.size
counter = hash
counter_start = counter
while True:
if counter == self.size:
counter = 0
if self.members[counter] == elem:
return True
elif self.status[counter] == 'Empty':
return False
counter += 1
if counter == counter_start:
return False
def delete(self, elem): # Removes an element from the hashtable
hash = ord(elem[0]) % self.size
counter = hash
counter_start = counter
while True:
if counter == self.size:
counter = 0
if self.members[counter] == elem:
self.members[counter] = None
self.status[counter] = 'Deleted'
break
counter += 1
if counter == counter_start:
raise Warning(f"{self} object has no member {elem}: .delete() attempt terminated")
break
# Testing code 'NewHashtable'
# Specified both .memstr() and .valstr() prints to check Member and Status tables at each step
n = NewHashtable(10)
print(n.memstr())
print(n.valstr())
print("\n")
n.insert("amy") #97
print(n.memstr())
print(n.valstr())
print("\n")
n.insert("chase") #99
print(n.memstr())
print(n.valstr())
print("\n")
n.insert("chris") #99
print(n.memstr())
print(n.valstr())
print("\n")
# Checks for membership
print(n.member("amy"))
print(n.member("chris"))
print(n.member("alyssa"))
n.delete("chase")
print(n.memstr())
print(n.valstr())
print("\n")
print(n.member("chris"))
print(n.memstr())
print(n.valstr())
print("\n")