21-b_hashtables.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # Basic hash table key/value pair
  2. class Pair:
  3. def __init__(self, key, value):
  4. self.key = key
  5. self.value = value
  6. self.next_node = None
  7. # Basic hash table
  8. # All storage values should be initialized to None
  9. class BasicHashTable:
  10. def __init__(self, capacity):
  11. self.capacity = capacity
  12. self.storage = [None for i in range(capacity)]
  13. # Research and implement the djb2 hash function
  14. def hash(string):
  15. tmp = 5381
  16. byte_array = string.encode('utf-8')
  17. for byte in byte_array:
  18. tmp = ((tmp * 33) ^ byte) % 0x100000000
  19. return tmp
  20. """
  21. def djb2(key):
  22. hash = 5381
  23. for c in key:
  24. hash = (hash * 33) + ord(c)
  25. return hash
  26. """
  27. def hash_table_insert(hash_table, key, value):
  28. # hash the key so you can compare the hashed keys
  29. hashed_key = hash(key)
  30. index = hashed_key % hash_table.capacity
  31. # Create a new node with the Pair class
  32. new_node = Pair(key, value)
  33. existing_node = hash_table.storage[index]
  34. if existing_node:
  35. # Look for an existing node with the same key
  36. if existing_node.key == key:
  37. # If you are overwriting a key with a different value, print a warning.
  38. print("You are overwriting an existing key's value.")
  39. existing_node.value == value
  40. existing_node = existing_node.next_node
  41. else:
  42. hash_table.storage[index] = new_node
  43. def hash_table_remove(hash_table, key):
  44. # same setup as insert
  45. hashed_key = hash(key)
  46. index = hashed_key % hash_table.capacity
  47. existing_node = hash_table.storage[index]
  48. if existing_node:
  49. last_node = None
  50. # while the current index exists
  51. while existing_node:
  52. if existing_node.key == key:
  53. # if last node is not None set it to the next node
  54. if last_node:
  55. last_node.next_node = existing_node.next_node
  56. # else set the key
  57. else:
  58. hash_table.storage[index] = existing_node.next_node
  59. last_node = existing_node
  60. existing_node = existing_node.next_node
  61. else:
  62. # If you try to remove a value that isn't there, print a warning.
  63. print("Unable to remove item")
  64. # Should return None if the key is not found.
  65. return None
  66. def hash_table_retrieve(hash_table, key):
  67. hashed_key = hash(key)
  68. index = hashed_key % hash_table.capacity
  69. existing_node = hash_table.storage[index]
  70. if existing_node:
  71. return existing_node.value
  72. def Testing():
  73. ht = BasicHashTable(16)
  74. hash_table_insert(ht, "line", "Here today...\n")
  75. hash_table_remove(ht, "line")
  76. if hash_table_retrieve(ht, "line") is None:
  77. print("...gone tomorrow (success!)")
  78. else:
  79. print("ERROR: STILL HERE")
  80. Testing()