def bst_sequences(root): """ This is a Python implementation of Gayle's solution from CtCI. I struggled with this problem so I just want to move past it. """ result = LinkedList() if root is None: result.insert(LinkedList()) return result prefix = LinkedList() prefix.add(root.data) #Recurse on left and right subtrees left_sequences = bst_sequences(root.left) right_sequences = bst_sequences(root.right) #Weave together each list from the left and right sides. while not left_sequences.is_empty(): left = left_sequences.get_first().data while not right_sequences.is_empty(): right = right_sequences.get_first().data weaved = LinkedList() weave_lists(left, right, weaved, prefix) result.add_all(weaved) return result
def sum_lists(a, b): a_num = 0 a_mult = 1 a_curr = a.head while a_curr is not None: a_num += a_curr.data * a_mult a_curr = a_curr._next a_mult *= 10 b_num = 0 b_mult = 1 b_curr = b.head while b_curr is not None: b_num += b_curr.data * b_mult b_curr = b_curr._next b_mult *= 10 output_num = a_num + b_num print(output_num) output_mult = 1 while output_num // (output_mult * 10) > 0: output_mult *= 10 output = LinkedList() if output_num == 0: output.insert(0) return output while output_num != 0: digit = int(output_num // output_mult) output.insert(digit) output_num = output_num - (digit * output_mult) output_mult /= 10 return output
def test_sum_lists(num_a, num_b): a = LinkedList() a_str = str(num_a) for digit in a_str: a.insert(int(digit)) b = LinkedList() b_str = str(num_b) for digit in b_str: b.insert(int(digit)) a.print_list() b.print_list() result = sum_lists(a, b) result.print_list()
def is_a_palindrome(li): """ This solution relies on the fact that the linked list implementation inserts nodes at the head of the list. It first scans the list to count the number of elements. Then we pop off the first half of the list while inserting into a new list. This will reverse the elements in a stack-like manner. If the original list contains an odd number of elements we discard the middle element. Finally, we check to see if the two lists we're left with match. This solution destroyes the original list, we could easily add a step to copy it into a new list first to avoid destroying it. """ n = 0 curr = li.head while curr is not None: n += 1 curr = curr._next li2 = LinkedList() k = n // 2 while k > 0: popped_node = li.get_first() li2.insert(popped_node.data) k -= 1 if n % 2 == 1: #Remove the middle element and discard it. _ = li.get_first() while not li2.is_empty(): li2_el = li2.get_first() li_el = li.get_first() if li2_el.data != li_el.data: return False return True
def test_loop_detection(): li = LinkedList() li.insert('C') li.insert('E') li.insert('D') c_node = li.head._next._next c_node._next = li.head li.head = c_node #Oops now we have a loop. li.insert('B') li.insert('A') loop_node = loop_detection(li) if loop_node is not None: print('Has loop at node %s.' % loop_node.data) else: print('Contains no loop.')
class TestLinkedList(unittest.TestCase): linked_list = None def setUp(self): self.linked_list = LinkedList() def test_init(self): self.assertEqual(self.linked_list.head, None, "Initial HEAD should be None") self.assertEqual(len(self.linked_list), 0, "Initial length should be zero") def test_len(self): self.assertEqual(len(self.linked_list), 0, "Newly initiated list's length should be zero") self.linked_list.insert(1) self.assertEqual(len(self.linked_list), 1, "List length should be 1") def test_list(self): node1 = self.linked_list.Node(1, None) node2 = self.linked_list.Node(2, node1) node3 = self.linked_list.Node(3, node2) self.linked_list.insert(1) self.linked_list.insert(2) self.linked_list.insert(3) self.assertEqual([node3, node2, node1], list(self.linked_list)) def test_str(self): self.linked_list.insert(1) self.linked_list.insert(2) self.linked_list.insert(3) self.assertEqual(str(self.linked_list), '[3, 2, 1]', "List should be printed as [3, 2, 1]") self.linked_list.delete(2) self.assertEqual(str(self.linked_list), '[3, 1]', "List should be printed as [3, 1]") self.linked_list.delete(3) self.assertEqual(str(self.linked_list), '[1]', "List should be printed as [1]") self.linked_list.delete(1) self.assertEqual(str(self.linked_list), '[]', "List should be printed as []") def test_insert(self): self.assertEqual( self.linked_list.insert(1), self.linked_list.Node(1, None), "Inserting 1 into list should return node with value=1") self.assertEqual(list(self.linked_list), [self.linked_list.Node(1)], "Inserting 1 into empty list should give [1]") self.linked_list.insert(3, 1) self.assertEqual(self.linked_list.head.next, self.linked_list.Node(3, None), "Inserting 3 into pos=1 of [1] should give [1,3]") self.linked_list.insert(2, 1) self.assertEqual( self.linked_list.head.next.value, self.linked_list.Node(2, None).value, "Inserting 2 into pos=1 of [1,3] should give [1,2,3]") def test_contains(self): self.linked_list.insert(1) self.linked_list.insert(2) self.linked_list.insert(3) self.assertEqual( 1 in self.linked_list, True, "After inserting 1 into the list, we should be able to find it there" ) self.assertEqual( 4 in self.linked_list, False, "After inserting 1 into the list, we should be able to find it there" ) #print(self.linked_list) def test_search(self): self.linked_list.insert(1) self.linked_list.insert(2) self.linked_list.insert(3) self.assertEqual( self.linked_list.search(2).value, self.linked_list.Node(2, None).value, "Searching for 2 in [3,2,1] should return node with value=2") self.assertEqual(self.linked_list.search(4), None, "Searching for 4 in [3,2,1] should return None") def test_delete(self): self.linked_list.insert(1) self.linked_list.insert(2) self.linked_list.insert(3) self.assertEqual( self.linked_list.delete(2).value, self.linked_list.Node(2, None).value, "Deleting 2 from [3,2,1] should return the node with value 2") self.linked_list.delete(3) self.assertEqual( self.linked_list.head, self.linked_list.Node(1, None), "Deleting 2 and 3 from [3,2,1] should leave the list as [1]")