Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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