def generate_tree_general(node_lst: List[ReadNode], root_index: int) -> HuffmanTree: """ Return the Huffman tree corresponding to node_lst[root_index]. The function assumes nothing about the order of the tree nodes in the list. >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 1, 1, 0)] >>> generate_tree_general(lst, 2) HuffmanTree(None, HuffmanTree(None, HuffmanTree(10, None, None), \ HuffmanTree(12, None, None)), \ HuffmanTree(None, HuffmanTree(5, None, None), HuffmanTree(7, None, None))) """ # 0 is leaf, 1 is not a leaf root = node_lst[root_index] tree = HuffmanTree(None, None, None) if root.l_type == 1: a = node_lst[root.l_data] tree.left = __generate_tree_gen_help(node_lst, a) else: tree.left = HuffmanTree(root.l_data, None, None) if root.r_type == 1: a = node_lst[root.r_data] tree.right = __generate_tree_gen_help(node_lst, a) else: tree.right = HuffmanTree(root.r_data, None, None) return tree
def generate_tree_general(node_lst: List[ReadNode], root_index: int) -> HuffmanTree: """ Return the Huffman tree corresponding to node_lst[root_index]. The function assumes nothing about the order of the tree nodes in the list. >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 1, 1, 0)] >>> generate_tree_general(lst, 2) HuffmanTree(None, HuffmanTree(None, HuffmanTree(10, None, None), \ HuffmanTree(12, None, None)), \ HuffmanTree(None, HuffmanTree(5, None, None), HuffmanTree(7, None, None))) >>> leftleft = HuffmanTree(None, HuffmanTree(20), HuffmanTree(71)) >>> left = HuffmanTree(None, HuffmanTree(3), leftleft) >>> right = HuffmanTree(None, HuffmanTree(9), HuffmanTree(10)) >>> tree = HuffmanTree(None, left, right) >>> generate_tree_general([ReadNode(1, 2, 1, 3), ReadNode(0, 4, 0, 12), ReadNode(1, 1, 0, 2), ReadNode(0, 9, 0, 10)], 0) HuffmanTree(None, HuffmanTree(None, HuffmanTree(None, \ HuffmanTree(4, None, None), HuffmanTree(12, None, None)), \ HuffmanTree(2, None, None)), HuffmanTree(None, HuffmanTree(9, None, None), \ HuffmanTree(10, None, None))) """ curr_node = node_lst[root_index] tree = HuffmanTree() if curr_node.l_type == 0: tree.left = HuffmanTree(curr_node.l_data) else: treex = generate_tree_general(node_lst, curr_node.l_data) tree.left = treex if curr_node.r_type == 0: tree.right = HuffmanTree(curr_node.r_data) else: treey = generate_tree_general(node_lst, curr_node.r_data) tree.right = treey return tree
def _post_order_helper(node_lst: List[ReadNode], root_index: int, flag: bool = True, right_index: int = 0) -> HuffmanTree: """ A helper function that generates a tree based on <node_lst> ReadNodes, and uses <root_index> and <flag> and <right_index> to do so. """ # if internal node if node_lst[root_index].l_type == 1 and flag: # Making Tree tree = HuffmanTree(None) tree.number = root_index - 1 - right_index # Creating Left and Right Trees tree.right = _post_order_helper(node_lst, tree.number, False) right_index = _find_height(tree.right) if right_index is None: right_index = 0 else: right_index = len(right_index) tree.left = _post_order_helper( node_lst, tree.number, True, right_index) return tree elif node_lst[root_index].r_type == 1 and not flag: # Making Tree tree = HuffmanTree(None) tree.number = root_index - 1 # Creating Left and Right Trees tree.right = _post_order_helper(node_lst, tree.number, False) right_index = _find_height(tree.right) if right_index is None: right_index = 0 else: right_index = len(right_index) tree.left = _post_order_helper( node_lst, tree.number, True, right_index) return tree elif node_lst[root_index].l_type == 0 and flag: return HuffmanTree(node_lst[root_index].l_data) elif node_lst[root_index].r_type == 0 and not flag: return HuffmanTree(node_lst[root_index].r_data) return HuffmanTree(None)
def __generate_tree_gen_help(node_lst: list, a: ReadNode) -> HuffmanTree: """Helper for generate tree general""" buff = HuffmanTree(None, None, None) if a.l_type == 0: buff.left = HuffmanTree(a.l_data, None, None) else: b = node_lst[a.l_data] buff.left = __generate_tree_gen_help(node_lst, b) if a.r_type == 0: buff.right = HuffmanTree(a.r_data, None, None) else: b = node_lst[a.r_data] buff.right = __generate_tree_gen_help(node_lst, b) return buff
def generate_tree_postorder(node_lst: List[ReadNode], root_index: int) -> HuffmanTree: """ Return the Huffman tree corresponding to node_lst[root_index]. The function assumes that the list represents a tree in postorder. >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 0, 1, 0)] >>> generate_tree_postorder(lst, 2) HuffmanTree(None, HuffmanTree(None, HuffmanTree(5, None, None), \ HuffmanTree(7, None, None)), HuffmanTree(None, HuffmanTree(10, None, None),\ HuffmanTree(12, None, None))) >>> lst = [ReadNode(0, 104, 0, 101), ReadNode(0, 119, 0, 114), \ ReadNode(1, 0, 1, 1), ReadNode(0, 100, 0, 111), ReadNode(0, 108, 1, 3), \ ReadNode(1, 2, 1, 4)] >>> tree = generate_tree_postorder(lst, len(lst)-1) >>> print(tree) HuffmanTree(None, HuffmanTree(None, HuffmanTree(None, HuffmanTree(104, None, None), HuffmanTree(101, None, None)), \ HuffmanTree(None, HuffmanTree(119, None, None), \ HuffmanTree(114, None, None))), \ HuffmanTree(None, HuffmanTree(108, None, None), \ HuffmanTree(None, HuffmanTree(100, None, None), \ HuffmanTree(111, None, None)))) >>> number_nodes(tree) >>> t = bytes_to_nodes(tree_to_bytes(tree)) >>> t [ReadNode(0, 104, 0, 101), ReadNode(0, 119, 0, 114), ReadNode(1, 0, 1, 1),\ ReadNode(0, 100, 0, 111), ReadNode(0, 108, 1, 3), ReadNode(1, 2, 1, 4)] >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 0, 1, 0)] >>> tree = generate_tree_postorder(lst, 2) >>> number_nodes(tree) >>> t = bytes_to_nodes(tree_to_bytes(tree)) >>> t [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), ReadNode(1, 0, 1, 1)] """ tree = HuffmanTree(None) tree.right = _post_order_helper(node_lst, root_index, False) right_index = _find_height(tree.right) if right_index is None: right_index = 0 else: right_index = len(right_index) tree.left = _post_order_helper(node_lst, root_index, True, right_index) _post_order_set_none(tree) return tree
def _gen_tree_helper(node_lst: List[ReadNode], root_index: int, flag: bool = True) -> HuffmanTree: """ A helper function that generates a tree based on <node_lst> ReadNodes, and uses <root_index> and <flag> to do so. """ # if internal node if node_lst[root_index].l_type == 1 and flag: # Making Tree tree = HuffmanTree(None) tree.number = node_lst[root_index].l_data # Creating Left and Right Trees tree.left = _gen_tree_helper(node_lst, tree.number, True) tree.right = _gen_tree_helper(node_lst, tree.number, False) return tree elif node_lst[root_index].r_type == 1 and not flag: # Making Tree tree = HuffmanTree(None) tree.number = node_lst[root_index].r_data # Creating Left and Right Trees tree.left = _gen_tree_helper(node_lst, tree.number, True) tree.right = _gen_tree_helper(node_lst, tree.number, False) return tree elif node_lst[root_index].l_type == 0 and flag: return HuffmanTree(node_lst[root_index].l_data) elif node_lst[root_index].r_type == 0 and not flag: return HuffmanTree(node_lst[root_index].r_data) return HuffmanTree(None)
def __generate_tree_postorder_helper(node_lst: list) -> HuffmanTree: """Helper for generate tree postorder.""" tree = HuffmanTree(None, None, None) for i in range(len(node_lst) - 1, -1, -1): a = node_lst[i] if a.l_type == 0 and a.r_type == 0: left_nodes = node_lst[0:i] right_nodes = node_lst[i:-1] if len(left_nodes) == 1: tree.left = HuffmanTree( None, HuffmanTree(left_nodes[0].l_data, None, None), HuffmanTree(left_nodes[0].r_data, None, None)) else: buffet = __generate_tree_postorder_helper(left_nodes) tree.left = buffet if len(right_nodes) == 1: tree.right = HuffmanTree( None, HuffmanTree(right_nodes[0].l_data, None, None), HuffmanTree(right_nodes[0].r_data, None, None)) else: buffet = __generate_tree_postorder_helper(right_nodes) tree.right = buffet break return tree
def generate_tree_postorder(node_lst: List[ReadNode], root_index: int) -> HuffmanTree: """ Return the Huffman tree corresponding to node_lst[root_index]. The function assumes that the list represents a tree in postorder. >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 0, 1, 0)] >>> generate_tree_postorder(lst, 2) HuffmanTree(None, HuffmanTree(None, HuffmanTree(5, None, None), \ HuffmanTree(7, None, None)), \ HuffmanTree(None, HuffmanTree(10, None, None), HuffmanTree(12, None, None))) """ # 0 is leaf, 1 is not a leaf root_index += 1 tree = HuffmanTree(None, None, None) for i in range(len(node_lst) - 1, -1, -1): a = node_lst[i] if a.l_type == 0 and a.r_type == 0: left_nodes = node_lst[0:i] right_nodes = node_lst[i:-1] if len(left_nodes) == 1: tree.left = HuffmanTree( None, HuffmanTree(left_nodes[0].l_data, None, None), HuffmanTree(left_nodes[0].r_data, None, None)) else: buffet = __generate_tree_postorder_helper(left_nodes) tree.left = buffet if len(right_nodes) == 1: tree.right = HuffmanTree( None, HuffmanTree(right_nodes[0].l_data, None, None), HuffmanTree(right_nodes[0].r_data, None, None)) else: buffet = __generate_tree_postorder_helper(right_nodes) tree.right = buffet break return tree
def generate_tree_general(node_lst: List[ReadNode], root_index: int) -> HuffmanTree: """ Return the Huffman tree corresponding to node_lst[root_index]. The function assumes nothing about the order of the tree nodes in the list. >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \ ReadNode(1, 1, 1, 0)] >>> tree = generate_tree_general(lst, 2) >>> result = HuffmanTree(None,HuffmanTree(None, \ ... HuffmanTree(10, None, None),\ ... HuffmanTree(12, None, None)), HuffmanTree(None,\ ... HuffmanTree(5, None, None),\ ... HuffmanTree(7, None, None))) >>> result == tree True >>> lst = [ReadNode(0, 104, 0, 101), ReadNode(0, 119, 0, 114), \ ReadNode(1, 0, 1, 1), ReadNode(0, 100, 0, 111), ReadNode(0, 108, 1, 3), \ ReadNode(1, 2, 1, 4)] >>> generate_tree_general(lst, len(lst)-1) HuffmanTree(None, HuffmanTree(None, HuffmanTree(None, \ HuffmanTree(104, None, None), HuffmanTree(101, None, None)), \ HuffmanTree(None, HuffmanTree(119, None, None), \ HuffmanTree(114, None, None))), \ HuffmanTree(None, HuffmanTree(108, None, None), \ HuffmanTree(None, HuffmanTree(100, None, None), \ HuffmanTree(111, None, None)))) >>> lst = [ReadNode(1, 1, 1, 2), ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12)] >>> tree = generate_tree_general(lst, 0) >>> number_nodes(tree) >>> bytes_to_nodes(tree_to_bytes(tree)) [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), ReadNode(1, 0, 1, 1)] """ tree = HuffmanTree(None) tree.left = _gen_tree_helper(node_lst, root_index, True) tree.right = _gen_tree_helper(node_lst, root_index, False) return tree