def test_queue(): class Element(HasDuration): def __init__(self, v, d): self.val = v self.dur = d def duration(self) -> int: return self.dur def __repr__(self): return f"Element({self.val})" def advance(): return frozenset(e.val for e in queue.advance()) queue = Queue() queue.extend([Element("a_0", 1), Element("b_0", 2), Element("d_0", 4), Element("c_0", 3)]) queue.append(Element("a_1", 1)) assert advance() == {"a_0", "a_1"} queue.extend([Element("b_1", 1), Element("e_0", 4)]) assert advance() == {"b_0", "b_1"} assert advance() == {"c_0"} assert advance() == {"d_0"} assert advance() == {"e_0"} assert advance() == set() queue.append(Element("f_0", 5)) for _ in range(4): assert advance() == set() assert advance() == {"f_0"}
def earliest_ancestor(ancestors, starting_node): # create a dictionary struct = {} # Loop through each pair in the ancestor list for pair in ancestors: # Parent is the first value of pair parent = pair[0] # Child is the second value of pair child = pair[1] # If Child is not in 'struct', add it if child not in struct: struct[child] = [] # Then add the parents of each child to their list in the dict struct[child].append(parent) # Create a queue q = Queue() # Append the starting node q.enqueue([starting_node]) # Set a default longest node to store the largest distance # index 0 and the last node - as it corresponds with the longest distance longest_node = [0, -1] # Check if the queue is empty while len(q) > 0: # pop the first path from the queue curr_path = q.popleft() # get the last node in the path last_node = curr_path[-1] # Check if the last node is in the dictionary if last_node not in struct: # if the curr_path is longer than the previous_path, that will be the new longest path if len(curr_path ) > longest_node[0] and last_node > longest_node[1]: # store the new longest_node longest_node = [len(curr_path), last_node] # else, if the last_node does have parents else: # loop through each parent and queue up # a path from the current path to each parent for x in struct[last_node]: q.append(curr_path + [x]) # if the longest_node is = starting_node, return -1 as the starting_node has no parents if longest_node[1] == starting_node: return -1 # Else return the node furthest away, which is longest_node[1] else: return longest_node[1]
def breadth_first_traverse(root): """breadth-first traversal or "level order traversal" algorithm: queue. """ if not root: return q = Queue([root], debug=True) while q: p = q.pop(0) yield p if p.left: q.append(p.left) if p.right: q.append(p.right)
def print_tree(root): """print tree """ if not root: return if not (root.left or root.right): print root.value #tree height tree_height = 0 q = Queue([(root, 0)]) #node, layer while q: p, layer = q.pop(0) if p.left or p.right: tree_height = layer + 1 if p.left: q.append((p.left, layer + 1)) if p.right: q.append((p.right, layer + 1)) node_width = 1 #node_width = 2 # * # / \ # * * tree_width = (2** (tree_height - 1)) * (node_width * 3 + 2) + 2 #2 extra space root_node_begin = (tree_width - node_width) / 2 #initialize line buffer count = 0 for layer in range(1, tree_height + 1): count += 2**(tree_height - layer) #the edge count += 1 #the node lines = [] for i in range(0, count + 1): lines.append([" "] * tree_width) #draw the tree to the buffer q = [(root, root_node_begin, 0, 0)] #(node, node_begin, layer, line_idx) while q: p, node_begin, layer, line_idx = q.pop(0) #print current node to buffer line = lines[line_idx] for i, c in enumerate("%s" % p.value): line[node_begin + i] = c if p.left: next_line_idx = line_idx + 2**(tree_height - layer - 1) + 1 #edge to left child next_node_begin = node_begin for i in range(line_idx + 1, next_line_idx): lines[i][next_node_begin - 1] = "/" next_node_begin -= 1 next_node_begin -= node_width q.append((p.left, next_node_begin, layer + 1, next_line_idx)) if p.right: next_line_idx = line_idx + 2**(tree_height - layer - 1) + 1 #edge to right child next_node_begin = node_begin + node_width for i in range(line_idx + 1, next_line_idx): lines[i][next_node_begin] = "\\" next_node_begin += 1 q.append((p.right, next_node_begin, layer + 1, next_line_idx)) #print out the tree for line in lines: print "".join(line)
def print_tree(root): """print tree """ if not root: return if not (root.left or root.right): print root.value #tree height tree_height = 0 q = Queue([(root, 0)]) #node, layer while q: p, layer = q.pop(0) if p.left or p.right: tree_height = layer + 1 if p.left: q.append((p.left, layer + 1)) if p.right: q.append((p.right, layer + 1)) node_width = 1 #node_width = 2 # * # / \ # * * tree_width = (2 ** (tree_height - 1)) * (node_width * 3 + 2) + 2 #2 extra space root_node_begin = (tree_width - node_width) / 2 #initialize line buffer count = 0 for layer in range(1, tree_height + 1): count += 2 ** (tree_height - layer) #the edge count += 1 #the node lines = [] for i in range(0, count + 1): lines.append([" "] * tree_width) #draw the tree to the buffer q = [(root, root_node_begin, 0, 0)] #(node, node_begin, layer, line_idx) while q: p, node_begin, layer, line_idx = q.pop(0) #print current node to buffer line = lines[line_idx] for i,c in enumerate("%s" % p.value): line[node_begin + i] = c if p.left: next_line_idx = line_idx + 2 ** (tree_height - layer - 1) + 1 #edge to left child next_node_begin = node_begin for i in range(line_idx + 1, next_line_idx): lines[i][next_node_begin - 1] = "/" next_node_begin -= 1 next_node_begin -= node_width q.append((p.left, next_node_begin, layer + 1, next_line_idx)) if p.right: next_line_idx = line_idx + 2 ** (tree_height - layer - 1) + 1 #edge to right child next_node_begin = node_begin + node_width for i in range(line_idx + 1, next_line_idx): lines[i][next_node_begin] = "\\" next_node_begin += 1 q.append((p.right, next_node_begin, layer + 1, next_line_idx)) #print out the tree for line in lines: print "".join(line)