def tournament_two_linked(A): """ Returns two largest values in A. Only works for lists whose length is a power of 2. Uses linked list, a topic not introduced until chapter 3. """ from algs.node import Node if len(A) < 2: raise ValueError('Must have at least two values') if len(A) % 2 == 1: raise ValueError('Only works for lists with even number of values.') tourn = None for i in range(0, len(A), 2): tourn = Node(Match(A[i], A[i+1]), tourn) # as long as multiple matches remaining while not tourn.next is None: results = None while tourn: results = Node(Match.advance(tourn.value, tourn.next.value), results) tourn = tourn.next.next tourn = results # Find where second is hiding! m = tourn.value largest = m.larger second = m.smaller while m.prior: m = m.prior if second < m.smaller: second = m.smaller return (largest,second)
def enqueue(self, val): """Enqueue new item to end of queue.""" if self.first is None: self.first = self.last = Node(val) else: self.last.next = Node(val) self.last = self.last.next
def test_node_2(self): node1 = Node('sample') node2 = Node('other', node1) self.assertEqual('other', node2.value) self.assertEqual('sample', node2.next.value) self.assertEqual(['other', 'sample'], list(node2))
def test_too_deep_recursion(self): from algs.node import Node first = n = Node(0) for i in range(1, 2000): n.next = Node(i) n = n.next self.assertEqual((2000 * 1999) / 2, sum_iterative(first)) # This raises an exception. With Python 3.5 and higher, this is # RecursionError, but to remain compatible with earlier 3.x I've # left as a RuntimeError with self.assertRaises(RuntimeError): sum_list(first)
def create_linked_list(alist): """Given a Python list, create linked list in same order.""" if len(alist) == 0: return None first = Node(alist[0]) first.next = create_linked_list(alist[1:]) return first
def add_edge(self, u, v): """Add edge (u,v) to a graph.""" if not u in self.adjacency: self.adjacency[u] = None if not v in self.adjacency: self.adjacency[v] = None n = self.adjacency[u] while n: if n.value == v: return # already there n = n.next self.adjacency[u] = Node(v, self.adjacency[u]) self.adjacency[v] = Node(u, self.adjacency[v]) self.E += 1
def test_damaged_recursive_data_structures(self): from ch06.expression import Expression, Value, add from algs.node import Node n = Node(3) n.next = n # This is dangerous! with self.assertRaises(RuntimeError): print(sum_list(n)) a = Expression(add, Value(1), Value(5)) a.left = a # This is dangerous! with self.assertRaises(RuntimeError): print(a.eval())
def tournament_two_losers(A): """ Returns two largest values in A. Only works for lists whose length is a power of 2. Each winner accumulates list of the values it beat, from which you call max() to find the second largest. """ from algs.node import Node if len(A) < 2: raise ValueError('Must have at least two values') if len(A) % 2 == 1: raise ValueError('Only works for lists with even number of values.') tourn = None for i in range(0, len(A), 2): tourn = Node(ExtendedMatch(A[i], A[i+1]), tourn) while not tourn.next is None: results = None while tourn: next_one = tourn.next.next tv = tourn.value tnv = tourn.next.value if tv.larger > tnv.larger: tv.add_loser(tnv.larger) tourn.next = results # Keep tourn results = tourn else: tnv.add_loser(tv.larger) tourn.next.next = results # Keey tourn.next results = tourn.next tourn = next_one tourn = results # Find where second is hiding! m = tourn.value largest = m.larger second = max(m.smaller) return (largest,second)
def push(self, val): """Push new item to the top of the stack.""" self.top = Node(val, self.top)
def test_node(self): n = Node('sample') self.assertEqual('[sample]', str(n))