diff --git a/Data Structures - Hashtables/Hash Table Implementation.py b/Data Structures - Hashtables/Hash Table Implementation.py index d238dad..78c76ec 100644 --- a/Data Structures - Hashtables/Hash Table Implementation.py +++ b/Data Structures - Hashtables/Hash Table Implementation.py @@ -1,67 +1,98 @@ class Hashtable: - def __init__(self): - """ - Create an array(self.mydict) with a bucket size - which is derived from the load factor. - The Load factor is a measure that decides when to increase the HashMap capacity to maintain the get() and put() operation complexity of O(1). - The default load factor of HashMap is 0.75f (75% of the map size). - Load Factor = (n/k) - where n is the number of max number of elements that can be stored dict - k is the bucket size - Optimal Load factor is around (2/3) such that the effect of hash collisions is minimum - """ - self.bucket = 16 - self.hashmap = [[] for i in range(self.bucket)] - - def __str__(self): - return str(self.__dict__) + def __init__(self): + """ + Create an array(self.mydict) with a bucket size - which is derived from the load factor. + The Load factor is a measure that decides when to increase the HashMap capacity to maintain the get() and put() operation complexity of O(1). + The default load factor of HashMap is 0.75f (75% of the map size). + Load Factor = (n/k) + where n is the number of max number of elements that can be stored dict + k is the bucket size + Optimal Load factor is around (2/3) such that the effect of hash collisions is minimum + """ + self.bucket = 16 + self.hashmap = [[] for i in range(self.bucket)] - def hash(self, key): - return len(key) % self.bucket - - def put(self, key, value): - """ - value may already be present - """ - hash_value = self.hash(key) - reference = self.hashmap[hash_value] - for i in range(len(reference)): - if reference[i][0] == key: - reference[i][1] = value - return None - reference.append([key, value]) - return None - - def get(self, key): - """ - Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key - """ - hash_value = self.hash(key) - reference = self.hashmap[hash_value] - for i in range(len(reference)): - if reference[i][0] == key: - return reference[i][1] - return -1 - - def remove(self, key): - """ - Removes the mapping of the specified value key if this map contains a mapping for the key - """ - hash_value = self.hash(key) - reference = self.hashmap[hash_value] - for i in range(len(reference)): - if reference[i][0] == key: - reference.pop(i) - return None - return None + def __str__(self): + return str(self.__dict__) -h=Hashtable() -h.put('grapes',1000) -h.put('apples',10) -h.put('ora',300) -h.put('banan',200) + def hash(self, key): + return len(key) % self.bucket + + def put(self, key, value): + """ + value may already be present + """ + hash_value = self.hash(key) + reference = self.hashmap[hash_value] + for i in range(len(reference)): + if reference[i][0] == key: + reference[i][1] = value + return None + reference.append([key, value]) + return None + + def get(self, key): + """ + Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key + """ + hash_value = self.hash(key) + reference = self.hashmap[hash_value] + for i in range(len(reference)): + if reference[i][0] == key: + return reference[i][1] + return -1 + + def remove(self, key): + """ + Removes the mapping of the specified value key if this map contains a mapping for the key + """ + hash_value = self.hash(key) + reference = self.hashmap[hash_value] + for i in range(len(reference)): + if reference[i][0] == key: + reference.pop(i) + return None + return None + + def keys(self): + """ + Prints out a list of the keys in the hashtable + """ + + hash_keys = [] + + for item in self.hashmap: + if item and len(item) > 1: + for i in item: + hash_keys.append(i[0]) + elif item: + hash_keys.append(item[0][0]) + return hash_keys + + def values(self): + """ + Prints out a list of the keys in the hashtable + """ + + hash_values = [] + + for item in self.hashmap: + if item and len(item) > 1: + for i in item: + hash_values.append(i[1]) + elif item: + hash_values.append(item[0][1]) + return hash_values + + +h = Hashtable() +h.put('grapes', 1000) +h.put('apples', 10) +h.put('ora', 300) +h.put('banan', 200) print(h.get('grapes')) print(h) h.remove('apples') print(h) - - +print(h.keys()) +print(h.values()) diff --git a/Data Structures - Linked Lists/Doubly Linked List.py b/Data Structures - Linked Lists/Doubly Linked List.py index d6cceda..122e761 100644 --- a/Data Structures - Linked Lists/Doubly Linked List.py +++ b/Data Structures - Linked Lists/Doubly Linked List.py @@ -1,15 +1,16 @@ class Node: - def __init__(self,data): + def __init__(self, data): self.data = data self.next = None self.prev = None + class DoublyLinkedList: def __init__(self): self.head = None self.tail = None - def append(self,data): + def append(self, data): new_node = Node(data) if self.head == None: self.head = new_node @@ -21,34 +22,34 @@ def append(self,data): self.tail = new_node self.length += 1 - def prepend(self,data): + def prepend(self, data): new_node = Node(data) new_node.next = self.head self.head.prev = new_node self.head = new_node self.length += 1 - def insert(self,index,data): + def insert(self, index, data): new_node = Node(data) - if index==0: + if index == 0: self.prepend(data) return if index >= self.length: self.append(data) return - else: + else: leader = self.traversetoindex(index - 1) holder = leader.next leader.next = new_node new_node.next = holder new_node.prev = leader holder.prev = new_node - self.length+=1 + self.length += 1 - def remove(self,index): - if index==0: - self.head=self.head.next - self.length-=1 + def remove(self, index): + if index == 0: + self.head = self.head.next + self.length -= 1 return if index == self.length-1: self.tail = self.tail.prev @@ -62,29 +63,43 @@ def remove(self,index): holder.prev = leader self.length -= 1 - - def traversetoindex(self,index): + def traversetoindex(self, index): curr_node = self.head i = 0 - while i!= index: + while i != index: curr_node = curr_node.next - i+=1 + i += 1 return curr_node def printt(self): temp = self.head while temp != None: - print(temp.data , end = ' ') + print(temp.data, end=' ') temp = temp.next print() - print('Length ' + str(self.length)) - - + print('Length = '+str(self.length)) + + def reverse(self): + new_next = None + self.tail = self.head + self.tail.prev = self.head.next + while self.head != None: + temp = self.head + self.head = self.head.next + if self.head != None: + self.head.prev = self.head.next + temp.next = new_next + new_next = temp + self.head = temp + + d = DoublyLinkedList() d.append(10) d.append(5) d.append(6) d.prepend(1) -d.insert(2,22) +d.insert(2, 22) d.remove(3) d.printt() +d.reverse() +d.printt() diff --git a/Recursion/Fibonacci.py b/Recursion/Fibonacci.py index 552b6ab..94c4c36 100644 --- a/Recursion/Fibonacci.py +++ b/Recursion/Fibonacci.py @@ -11,12 +11,23 @@ def fib(num): return total +def fib_2(num): + """ + Second methon using iteration to generate fibonacci number + """ + arr = [0, 1] + for i in range(2, num+1): + arr.append(arr[i-1]+arr[i-2]) + return arr[num] + + def fibonacci(num): if num < 2: return num - return fib(num-1) + fib(num-2) + return fibonacci(num-1) + fibonacci(num-2) print([fib(i) for i in range(10)]) +print([fib_2(i) for i in range(10)]) print([fibonacci(i) for i in range(10)]) print([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])