def put(self, key, value): """ Store the value with the given key. Hash collisions should be handled with Linked List Chaining. Implement this. """ # find the index index = self.hash_index(key) # create a hash table entry object hash_obj = HashTableEntry(key=key, value=value) # if there is no hash table entry at the index if self.buckets[index] is None: # create a linked list ll = LinkedList() # set the hash table entry as the head ll.head = hash_obj # store the linked list at the index of the hash table self.buckets[index] = ll # update entries self.entries += 1 # if there is a linked list of hash table entries at the index else: # get the head hash entry cur = self.buckets[index].head # traverse the linked list while cur is not None: # If the key has been used before if cur.key == key: # update the value cur.value = value # exit method return # move onto the next hash entry else: cur = cur.next # if there are no matches # insert the hash entry at the head of the list self.buckets[index].insert_at_head(hash_obj) # update the entries self.entries += 1
def test_areIntersecting(): ''' test for areIntersecting method ''' print 'Testing areIntersecting... ', node2, node3 = Node(2), Node(3) lst1 = LinkedList().add(Node(1)).add(node2).add(node3) lst2 = LinkedList().add(Node(4)).add(Node(5)) intersecting, node = areIntersecting(lst1, lst2) assert not intersecting assert node is None lst2.tail.next = node2 lst2.tail = lst1.tail lst2.count += 2 intersecting, node = areIntersecting(lst1, lst2) assert intersecting assert node is node2 print 'Passed'
def sumLists(lst1, lst2): ''' find sum of the input lists and output as a list ''' curr1, curr2 = lst1.head, lst2.head result = LinkedList() carry = 0 while curr1 is not None and curr2 is not None: res = curr1.data + curr2.data + carry carry = res / 10 res = res % 10 result.add(Node(res)) curr1 = curr1.next curr2 = curr2.next rem = curr1 if curr2 is None else curr2 while rem is not None: res = rem.data + carry carry = 0 if res > 9: res = res - 10 carry = 1 result.add(Node(res)) rem = rem.next return result
class Stack: def __init__(self): self.items = LinkedList() def __repr__(self): return str(self.items) def __len__(self): return len(self.items) def is_empty(self): return self.items.is_empty() def peek(self): ''' shows the top of the stack ''' return self.items.head.data def push(self, data): ''' push data in the stack. ''' self.items.prepend(data) def pop(self): ''' pops data from the stack. return: data element ''' if not self.items.is_empty(): top = self.peek() res = self.items.delete(top) return res else: raise LookupError('empty stack')
def test_isPalindrome(): ''' test for isPalindrome methods ''' lst = LinkedList() lst.add(1).add(2).add(3) assert not isPalindrome(lst) assert not isPalin2(lst.head, lst.head)[0] lst.add(2).add(1) assert isPalindrome(lst) assert isPalin2(lst.head, lst.head)[0] print 'Test Passed.'
def test_hasLoop(): ''' test for hasLoop method ''' print 'Testing hasLoop method ... ', nodea = Node('a') lst = LinkedList() ignore = [lst.add(Node(x)) for x in range(4)] lst.add(nodea) ignore = [lst.add(Node(x)) for x in range(10)] assert not hasLoop(lst)[0] lst.tail.next = nodea result, node = hasLoop(lst) assert result assert node is nodea print 'Passed'
# determine if a linked list is circular ("last" node points to a node earlier in the list) # causes infinate loops in a lot of LL logic # use two pointers from llist import LinkedList def is_circular(llist): slow, fast = llist.head, llist.head while fast.next and fast.next.next: slow = slow.next fast = fast.next.next if slow is fast: return True return False l = LinkedList() for i in range(950): l.insert_first(f'node {i}') assert is_circular(l) == False end = l.get_last() node = l.get(300) end.next = node assert is_circular(l) print('All tests passed!')
def remove(self): if len(self) < 1: raise Exception("Cannot remove from empty Queue") node = self.head LinkedList.remove(self, node) return node.data
def add(self, item): node = Node(item) LinkedList.add(self, node)
# return middle node of linked list # if size is even, return node at end of first half of list # solve by only iterating over the list once # use two pointers - slow & fast # increment slow by 1, fast by 2 # when fast reaches end of list, slow should reference the middle element from llist import LinkedList def midpoint(llist): mid, end = llist.head, llist.head while end.next and end.next.next: mid = mid.next end = end.next.next return mid l = LinkedList() for i in range(9): l.insert_first(f'node {i}') # middle is 'node 4' assert midpoint(l).data == 'node 4' l.insert_first('another node') # size is now odd assert midpoint(l).data == 'node 5' print('All tests passed!')
# assume n is less than length of list # another two-pointer solution from llist import LinkedList def nth_from_end(ls, n): aft, forward = ls.head, ls.head for _ in range(n): forward = forward.next while forward.next: aft = aft.next forward = forward.next return aft l = LinkedList() for i in range(20): l.insert_first(f'node {i}') # for el in l: # print(el.data) assert nth_from_end(l, 5).data == 'node 5' assert nth_from_end(l, 19).data == 'node 19' assert nth_from_end(l, 1).data == 'node 1' assert nth_from_end(l, 0).data == 'node 0' print('All tests passed!')
def __init__(self): self.items = LinkedList()
def llist(): return LinkedList()
import logger from llist import LinkedList import time log = logger.getLogger(__name__) log.info("generating linked list...") start_time = time.time() llist = LinkedList(range(0, 100, 2)) log.info("elements in the linked list are:") log.info([node for node in llist]) log.info("copying linked list...") llist_copy = llist.copy_linked_list() log.info("elements in the copy of the linked list are:") log.info([node for node in llist_copy]) log.info("--- execution time = %s seconds ---" % (time.time() - start_time))