def merge(left, right): ''' function merge(left, right) var result := empty list while left is not empty and right is not empty do if first(left) <= first(right) then append first(left) to result left := rest(left) else append first(right) to result right := rest(right) while left is not empty do append first(left) to result left := rest(left) while right is not empty do append first(right) to result right := rest(right) return result ''' result = DoubleLinkedList() while left.count() > 0 and right.count() > 0: if left.begin.value <= right.begin.value: result.push(left.unshift()) else: result.push(right.unshift()) while left.count() > 0: result.push(left.unshift()) while right.count() > 0: result.push(right.unshift()) return result
def quick_sort(numbers): if numbers.count() <= 1: return numbers result = DoubleLinkedList() # There are many different strategies for picking a pivot # This allows for flexibility in defining the pivot pivotIndex = randint(1, numbers.count()) index = 1 pivot = numbers.begin while index != pivotIndex: pivot = pivot.next index += 1 # Now send the list to partition() and get back two lists, # one that contains values less than, and one that has # values greater than the pivot left, right = sorting.partition(numbers, pivot) # Prepend the sorted left side to the pivot and append the # sorted right side sorting.quick_sort(left) while left.count() > 0: result.push(left.unshift()) result.push(pivot) sorting.quick_sort(right) while right.count() > 0: result.push(right.unshift()) return result
def merge_sort(numbers): ''' Pseudocode from wikipedia: function merge_sort(list m) if length of m <= 1 then return m var left := empty list var right := empty list for each x with index i in m do if i < (length of m)/2 then add x to left else add x to right left := merge_sort(left) right := merge_sort(right) return merge(left, right) ''' if numbers.count() <= 1: return numbers left = DoubleLinkedList() right = DoubleLinkedList() split = numbers.count() / 2 while numbers.count() > 0: if split > 0: left.push(numbers.unshift()) split -= 1 else: right.push(numbers.unshift()) left = sorting.merge_sort(left) right = sorting.merge_sort(right) return sorting.merge(left, right)
def test_double_linked_list(): """ Test list creation and insert method """ l = DoubleLinkedList() assert l.head == None assert l.tail == None assert l._size == 0 for element in [1, 2]: l.append(element) print('Value: {}, Type: {}'.format(l.head.value, type(l.head.value))) assert l.head.value == 1 assert l.tail.value == 2 assert l._size == 2 assert l.head.next.value == 2 assert l.tail.next == None
def test_append(): """ Test append method """ l = DoubleLinkedList() l.append(1) assert l.tail.value == 1 assert l.tail.next == None assert l.head.value == 1 assert l._size == 1 l.append(2) assert l.tail.value == 2 assert l.tail.next == None assert l.head.value == 1 assert l.head.next.value == 2 assert l._size == 2
def test_double_linked_list(): """ Test list creation and insert method """ l = DoubleLinkedList() assert l.head == None assert l.tail == None assert l._size == 0 for element in [1,2]: l.append(element) print('Value: {}, Type: {}'.format(l.head.value, type(l.head.value))) assert l.head.value == 1 assert l.tail.value == 2 assert l._size == 2 assert l.head.next.value == 2 assert l.tail.next == None
class Queue(object): '''Stack is a composition of LinkedList''' def __init__(self, input=None): self.queue = DoubleLinkedList(input) def enqueue(self, val): self.queue.insert(val) def dequeue(self): shift_val = self.queue.shift() return shift_val def size(self): return self.queue._size() def peek(self): return self.queue.tail.data
def partition(numbers, pivot): '''The original partition scheme described by C.A.R. Hoare uses two indices that start at the ends of the array being partitioned, then move toward each other, until they detect an inversion: a pair of elements, one greater than or equal to the pivot, one lesser or equal, that are in the wrong order relative to each other. The inverted elements are then swapped''' left = DoubleLinkedList() right = DoubleLinkedList() numbers.detach_node(pivot) i = numbers.begin j = numbers.end while True: while i.value <= pivot.value: if i == numbers.end: break i = i.next while j.value >= pivot.value: if j == numbers.begin: break j = j.prev # Trying to avoid having to tack on index numbers to my # double linked lists. Using a "position()" function to # calculate the position instead if sorting.position(numbers, i) < sorting.position(numbers, j): i.value, j.value = j.value, i.value else: if i.value > pivot.value: split = sorting.position(numbers, i) - 1 else: split = sorting.position(numbers, i) while numbers.count() > 0: if split > 0: # print("split=",split,"num=",numbers.begin) left.push(numbers.unshift()) split -= 1 else: # print("split=",split,"num=",numbers.begin) right.push(numbers.unshift()) break return left, right
def test_remove(): """ Test remove """ l = DoubleLinkedList() with pytest.raises(LookupError): l.remove(1) for i in range(1, 4): l.append(i) assert l.remove(2) assert l.head.value == 1 assert l.head.next.value == 3 assert l.tail.value == 3 assert l._size == 2
def test_shift(): """ Test shift """ l = DoubleLinkedList() with pytest.raises(LookupError): l.shift() for i in range(1, 4): l.append(i) assert l._size == 3 assert l.shift() == 3 assert l.head.value == 1 assert l.tail.value == 2 assert l._size == 2 assert l.shift() == 2 assert l.head.value == 1 assert l.tail.value == 1 assert l._size == 1
def test_shift(): """ Test shift """ l = DoubleLinkedList() with pytest.raises(LookupError): l.shift() for i in range(1,4): l.append(i) assert l._size == 3 assert l.shift() == 3 assert l.head.value == 1 assert l.tail.value == 2 assert l._size == 2 assert l.shift() == 2 assert l.head.value == 1 assert l.tail.value == 1 assert l._size == 1
def test_remove(): """ Test remove """ l = DoubleLinkedList() with pytest.raises(LookupError): l.remove(1) for i in range(1,4): l.append(i) assert l.remove(2) assert l.head.value == 1 assert l.head.next.value == 3 assert l.tail.value == 3 assert l._size == 2
class Deque(object): '''Deque is a composition of Double Linked List''' def __init__(self, input=None): '''create doubly linked list''' self.deque = DoubleLinkedList(input) def append(self, val): self.deque.append(val) def append_left(self, val): self.deque.insert(val) def pop(self): return self.deque.pop() def pop_left(self): return self.deque.shift() def peek(self): try: return self.deque.head.data except AttributeError: return None def peek_left(self): try: return self.deque.tail.data except AttributeError: return None def size(self): size = 0 current_spot = self.deque.head while current_spot: size += 1 current_spot = current_spot.toward_tail return size
def __init__(self, num_buckets=256): """initialize a map""" self.map = DoubleLinkedList() for i in range(0, num_buckets): self.map.push(DoubleLinkedList())
class Dictionary(object): def __init__(self, num_buckets=256): """initialize a map""" self.map = DoubleLinkedList() for i in range(0, num_buckets): self.map.push(DoubleLinkedList()) def has_key(self, key): return hash(key) % self.map.count() def get_bucket(self, key): bucket_id = self.has_key(key) return self.map.get(bucket_id) def get_slot(self, key, default=None): """ Returns either the bucket and node for a slot, or None, None """ bucket = self.get_bucket(key) if bucket: node = bucket.begin i = 0 while node: if key == node.value[0]: return bucket, node else: node = node.next i += 1 # fall through for both if and while above return bucket, None def get(self, key, default=None): bucket, node = self.get_slot(key, default=default) return node and node.value[1] or node def set(self, key, value): """Sets the key to the value, replacing any existing value.""" bucket, slot = self.get_slot(key) if slot: # the key exists, replace it slot.value = (key, value) else: # the key does not, append to create it bucket.push((key, value)) def delete(self, key): """Deletes the given key from the Map.""" bucket = self.get_bucket(key) node = bucket.begin while node: k, v = node.value if key == k: bucket.detach_node(node) break def list(self): """Prints out what's in the Map.""" bucket_node = self.map.begin while bucket_node: slot_node = bucket_node.value.begin while slot_node: print(slot_node.value) slot_node = slot_node.next bucket_node = bucket_node.next
def __init__(self, input=None): '''create doubly linked list''' self.deque = DoubleLinkedList(input)
def test_append_list(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList((4, 5, 65)) new_list.append([45, 'nine', False]) assert new_list.tail.data == [45, 'nine', False]
def test_insert_int(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList((4, 5, 65)) new_list.insert(45) assert new_list.head.data == 45
def test_append_int(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList((4, 5, 65)) new_list.append(45) assert new_list.tail.data == 45
def test_insert_str(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList((4, 5, 65)) new_list.insert('dog') assert new_list.head.data == 'dog'
def test_remove(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList(LIST_INPUT) new_list.remove(9) new_list.remove(7) assert new_list.head.data == 8
def test_linked_node_init_next(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList((3, 4, 5)) assert new_list.head.toward_tail.data == 4
def test_shift(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList(LIST_INPUT) assert new_list.shift() == 6
def test_pop(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList(LIST_INPUT) new_list.pop() assert new_list.pop() == 8
def test_empty_double_linked(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList() new_list.insert(999) assert new_list.shift() == 999
def __init__(self, input=None): self.queue = DoubleLinkedList(input)
def test_remove_error(): from double_linked import DoubleLinkedList new_list = DoubleLinkedList(LIST_INPUT) with pytest.raises(ValueError): new_list.remove('eight')