예제 #1
0
def find_code(int_, tree):
    '''Return the code corresponding to the symbol int in tree.

    @type int: int
    @type tree: HuffmanNode
    @rtype: str

    >>> a = HuffmanNode(None, HuffmanNode(None, HuffmanNode(1), \
HuffmanNode(3)), HuffmanNode(2))
    >>> find_code(2, a)
    '1'
    '''
    code = ""
    if tree.right and tree.left:
        if int_ in get_leaves(tree.left):
            code = '0'
            return code + find_code(int_, tree.left)
        elif int_ in get_leaves(tree.right):
            code = '1'
            return code + find_code(int_, tree.right)
    return code
예제 #2
0
파일: huffman.py 프로젝트: cicizh/Huffman
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that the list represents a tree in postorder.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 20, 0, 16), ReadNode(0, 26, 0, 23), \
    ReadNode(0, 15, 1, 0), ReadNode(1, 0, 1, 0)]
    >>> tree_example = HuffmanNode(None, HuffmanNode(None, \
    HuffmanNode(20, None, None), HuffmanNode(16, None, None)), \
    HuffmanNode(None, HuffmanNode(15, None, None), HuffmanNode(None, \
    HuffmanNode(26, None, None), HuffmanNode(23, None, None))))
    >>> tree_example == generate_tree_postorder(lst, 3)
    True
    """
    if node_lst[root_index].l_type == 0 and node_lst[root_index].r_type == 0:
        node = HuffmanNode(None, HuffmanNode(node_lst[root_index].l_data),
                           HuffmanNode(node_lst[root_index].r_data))
    elif node_lst[root_index].l_type == 0 and node_lst[root_index].r_type == 1:
        node = HuffmanNode(None, HuffmanNode(node_lst[root_index].l_data),
                           generate_tree_postorder(node_lst, (root_index - 1)))
    elif node_lst[root_index].l_type == 1 and node_lst[root_index].r_type == 0:
        node = HuffmanNode(None,
                           generate_tree_postorder(node_lst, (root_index - 1)),
                           HuffmanNode(node_lst[root_index].r_data))
    else:
        right = generate_tree_postorder(node_lst, (root_index - 1))
        number_nodes(right)
        new_index = (root_index - 1) - (right.number + 1)
        node = HuffmanNode(None,
                           generate_tree_postorder(node_lst, new_index), right)
    number_nodes(node)
    return node
예제 #3
0
def get_leaves(tree):
    '''Return a list containing the symbols of leaves.

    @type tree: HuffmanNode
    @rtype: list[int]

    >>> a = HuffmanNode(None, HuffmanNode(None, HuffmanNode(1),\
HuffmanNode(3)), HuffmanNode(2))
    >>> b = get_leaves(a)
    >>> b.sort()
    >>> b
    [1, 2, 3]
    '''
    if not tree.left and not tree.right:
        return [tree.symbol]
    else:
        if tree.left and tree.right:
            return get_leaves(tree.left) + get_leaves(tree.right)
        elif tree.left:
            return get_leaves(tree.left)
        else:
            return get_leaves(tree.right)
예제 #4
0
    def postorder_helper(node_lst, root_index):  # helper function
        """ Return the tuple with root of the Huffman tree corresponding
            to node_lst[root_index].

            The function assumes that the list represents a tree in postorder.

            @param list[ReadNode] node_lst: a list of ReadNode objects
            @param int root_index: index in the node list
            @rtype: tuple of (HuffmanNode, int)
        """
        track_index, track_node = root_index, node_lst[root_index]
        tree = HuffmanNode()  # assign variables for node_lst and root_lst
        if track_node.r_type == 0:  # start traversing from right
            tree.right = HuffmanNode(track_node.r_data)  # if leaf
        else:
            right = postorder_helper(node_lst, track_index - 1)  # recurse down
            tree.right, track_index = right[0], right[1]  # modify right
            # and track new corresponding index
        if track_node.l_type == 0:  # start traversing left side
            tree.left = HuffmanNode(track_node.l_data)  # if leaf
        else:  # do recursion on left side now and modify tree and track index
            left = postorder_helper(node_lst, track_index - 1)
            tree.left, track_index = left[0], left[1]
        return tree, track_index  # return tuple
예제 #5
0
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in the list.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode
    """
    tree = HuffmanNode(None, None, None)

    def helper4(node_lst, root_index, tree):
        """Helps modify the inputted tree, by adding Nodes from the
        given node_lst, and root_index.
        
        @param lst[ReadNode] node_lst a list of ReadNode objects
        @param root_index, int; the root of the tree
        @param tree, HuffmanNode tree
        
        @rtype: NoneType
        """
        l_data = node_lst[root_index].l_data
        r_data = node_lst[root_index].r_data
        if node_lst[root_index].l_type == 0:
            tree.left = HuffmanNode(l_data)
        else:
            tree.left = HuffmanNode(None, None, None)
            helper4(node_lst, l_data, tree.left)
        if node_lst[root_index].r_type == 0:
            tree.right = HuffmanNode(r_data)
        else:
            tree.right = HuffmanNode(None, None, None)
            helper4(node_lst, r_data, tree.right)
        return

    helper4(node_lst, root_index, tree)
    return tree
예제 #6
0
def huffman_tree_helper(lst):
    """
    Delete the first two nodes and their frequencies in lst, and
    append a new node from the sum of those two nodes.

    @param list of lists lst:
    @rtype: None
    """
    # take a list of lists with each inner list representing a "node"
    while len(lst) > 1:
        # delete two lowest nodes
        store = [lst[0], lst[1]]
        lst.remove(lst[0])
        lst.remove(lst[0])
        count = 0
        # find the sum
        for item in store:
            count += item[0]

        sum_list = [count, HuffmanNode(None, store[0][1], store[1][1])]
        # append the node of the sum to the double_list
        lst.append(sum_list)
        lst.sort()
예제 #7
0
def get_huffman_leaves(tree):
    '''Return the leaves in tree.

    @type tree: HuffmanNode
    @rtype: list[HuffmanNode]

    >>> a = HuffmanNode(None, HuffmanNode(None, HuffmanNode(1),\
HuffmanNode(3)), HuffmanNode(2))
    >>> b = get_huffman_leaves(a)
    >>> b
    [HuffmanNode(1, None, None), HuffmanNode(3, None, None), HuffmanNode(2, \
None, None)]
    '''
    if tree.is_leaf():
        return [tree]
    else:
        if tree.left and tree.right:
            return get_huffman_leaves(tree.left) + \
                   get_huffman_leaves(tree.right)
        elif tree.left:
            return get_huffman_leaves(tree.left)
        else:
            return get_huffman_leaves(tree.right)
예제 #8
0
def number_nodes(tree):
    """ Number internal nodes in tree according to postorder traversal;
    start numbering at 0.

    @param HuffmanNode tree:  a Huffman tree rooted at node 'tree'
    @rtype: NoneType

    >>> left = HuffmanNode(None, HuffmanNode(3), HuffmanNode(2))
    >>> right = HuffmanNode(None, HuffmanNode(9), HuffmanNode(None, \
HuffmanNode(10)))
    >>> tree = HuffmanNode(None, left, right)
    >>> number_nodes(tree)
    >>> tree.left.number
    0
    >>> tree.right.right.number
    1
    >>> tree.right.number
    2
    >>> tree.number
    3
    """
    list_ = find_internal(tree)
    for node in list_:
        node.number = list_.index(node)
예제 #9
0
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].
    The function assumes nothing about the order of the nodes in the list.
    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode
    #>>> lst = [ReadNode(1, 0, 1, 0), ReadNode(0, 5, 0, 7), \
    #ReadNode(0, 10, 0, 12)]
    #>>> generate_tree_general(lst, 0)
    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> generate_tree_general(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None), \
HuffmanNode(12, None, None)), \
HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
    """

    nodes = {}

    for i in range(len(node_lst)):
        node = HuffmanNode(None)
        node.number = i
        nodes[i] = node

    # Sequences left and right 'branches' of Huffman Tree
    for i in range(len(node_lst)):

        if node_lst[i].l_type == 0:
            nodes[i].left = HuffmanNode(node_lst[i].l_data)
        else:
            nodes[i].left = nodes[node_lst[i].l_data]

        if node_lst[i].r_type == 0:
            nodes[i].right = HuffmanNode(node_lst[i].r_data)
        else:
            nodes[i].right = nodes[node_lst[i].r_data]

    # Root of tree becomes dict value at root_index
    tree = nodes[root_index]
    return tree
예제 #10
0
    def generate_huffman(r_node):
        """ Return a HuffmanNode from a ReadNode.

        @param ReadNode r_node: a ReadNode to convert
        @rtype: HuffmanNode

        >>> huff = generate_huffman(ReadNode(0, 10, 0, 12))
        >>> huff == HuffmanNode(None, HuffmanNode(10), HuffmanNode(12))
        True
        >>> huff = generate_huffman(ReadNode(1, 0, 1, 0))
        >>> huff == HuffmanNode(None, HuffmanNode(), HuffmanNode())
        True
        """
        if r_node.l_type == 0 and r_node.r_type == 0:
            return HuffmanNode(None, HuffmanNode(r_node.l_data),
                               HuffmanNode(r_node.r_data))
        elif r_node.l_type == 0 and r_node.r_type == 1:
            return HuffmanNode(None, HuffmanNode(r_node.l_data), HuffmanNode())
        elif r_node.l_type == 1 and r_node.r_type == 0:
            return HuffmanNode(None, HuffmanNode(), HuffmanNode(r_node.r_data))
        else:
            return HuffmanNode(None, HuffmanNode(), HuffmanNode())
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in node_lst.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in 'node_lst'
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> generate_tree_general(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None), \
HuffmanNode(12, None, None)), \
HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
    """
    tree = HuffmanNode(None)
    if len(node_lst) == 0:
        return

    current = node_lst[root_index]

    if current.l_type == 0 and current.r_type == 0:
        tree.left = HuffmanNode(current.l_data)
        tree.right = HuffmanNode(current.r_data)

    if current.l_type == 0:
        tree.left = HuffmanNode(current.l_data)
    if current.r_type == 0:
        tree.right = HuffmanNode(current.r_data)

    if current.l_type == 1:
        tree.left = generate_tree_general(node_lst, current.l_data)

    if current.r_type == 1:
        tree.right = generate_tree_general(node_lst, current.r_data)

    return tree
예제 #12
0
    def generate_huffman(r_node):
        """ Return a HuffmanNode from a ReadNode.

        @param ReadNode r_node: a ReadNode to convert
        @rtype: HuffmanNode

        >>> huff = generate_huffman(ReadNode(0, 5, 0, 7))
        >>> huff == HuffmanNode(None, HuffmanNode(5), HuffmanNode(7))
        True
        >>> huff = generate_huffman(ReadNode(1, 1, 1, 0))
        >>> huff == HuffmanNode(None, HuffmanNode(), HuffmanNode())
        True
        >>> huff.left.number
        1
        >>> huff.right.number
        0
        """
        if r_node.l_type == 0 and r_node.r_type == 0:
            return HuffmanNode(None, HuffmanNode(r_node.l_data),
                               HuffmanNode(r_node.r_data))
        elif r_node.l_type == 0 and r_node.r_type == 1:
            huff_node = HuffmanNode(None, HuffmanNode(r_node.l_data),
                                    HuffmanNode())
            huff_node.right.number = r_node.r_data
            return huff_node
        elif r_node.l_type == 1 and r_node.r_type == 0:
            huff_node = HuffmanNode(None, HuffmanNode(),
                                    HuffmanNode(r_node.r_data))
            huff_node.left.number = r_node.l_data
            return huff_node
        else:
            huff_node = HuffmanNode(None, HuffmanNode(), HuffmanNode())
            huff_node.left.number = r_node.l_data
            huff_node.right.number = r_node.r_data
            return huff_node
예제 #13
0
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that node_lst represents a tree in postorder.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in 'node_lst'
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), \
HuffmanNode(7, None, None)), \
HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """
    if root_index not in range(len(node_lst)):
        return None
    else:
        a = node_lst[root_index]
        g = HuffmanNode(None, None, None)

        if a.r_type == 0 and a.l_type == 0:
            g.left = HuffmanNode(a.l_data, None, None)
            g.right = HuffmanNode(a.r_data, None, None)
        if a.r_type == 0 and a.l_type == 1:
            g.right = HuffmanNode(a.r_data, None, None)
            g.left = generate_tree_postorder(node_lst, root_index - 1)
        if a.r_type == 1 and a.l_type == 0:
            a.left = HuffmanNode(a.l_data, None, None)
            g.right = generate_tree_postorder(node_lst, root_index - 1)
        if a.r_type == 1 and a.l_type == 1:
            g.left = generate_tree_postorder(node_lst, root_index - 2)
            g.right = generate_tree_postorder(node_lst, root_index - 1)
    return g
예제 #14
0
def generate_tree_postorder(node_lst, root_index):
    """Return the root of the Huffman tree corresponding
    to node_lst[root_index].
    The function assumes that the list represents a tree in postorder.
    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode
    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), \
    HuffmanNode(7, None, None)), \
    HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """

    tree = HuffmanNode()
    if len(node_lst) == 1:
        tree.left = HuffmanNode(node_lst[0].l_data)
        tree.right = HuffmanNode(node_lst[0].r_data)
        return tree

    rn = node_lst[root_index]

    if rn.l_type == 1:
        if rn.l_data == 0:
            tree.right = generate_tree_general([node_lst[1]], root_index)
        else:
            tree.left = generate_tree_general([node_lst[0]], root_index)
    else:
        tree.left = HuffmanNode(rn.l_data)

    if rn.r_type == 1:
        if rn.r_data == 1:
            tree.right = generate_tree_general([node_lst[1]], root_index)
        else:
            tree.left = generate_tree_general([node_lst[0]], root_index)
    else:
        tree.right = HuffmanNode(rn.r_data)

    return tree
예제 #15
0
def helper_generate_tree(node_lst):
    """A helper functions to generate a tree"""
    huffman_lst = []

    for element in list(node_lst):  #changing list to huffman nodes
        if element.l_type == 0 and element.r_type == 0:  # both leaves
            left = HuffmanNode(element.l_data)
            right = HuffmanNode(element.r_data)

        elif (element.l_type == 0 and element.r_type == 1):  # left leaf
            left = HuffmanNode(element.l_data)
            right = HuffmanNode()
            right.number = element.r_data

        elif (element.l_type == 1 and element.r_type == 0):  # right leaf
            left = HuffmanNode()
            left.number = element.l_data
            right = HuffmanNode(element.r_data)

        else:  # no leaves
            left = HuffmanNode()
            left.number = element.l_data
            right = HuffmanNode()
            right.number = element.r_data

        node = HuffmanNode(None, left, right)
        huffman_lst.append(node)
    return huffman_lst
예제 #16
0
파일: huffman.py 프로젝트: jachsu/huffman
def make_node(n, i):
    """
    Make the elements in node_lst HuffmanNodes.
    """
    t = HuffmanNode()
    if not n.l_type:
        t.left = HuffmanNode(n.l_data)
    else:
        t.left = HuffmanNode()
        t.left.number = n.l_data
    if not n.r_type:
        t.right = HuffmanNode(n.r_data)
    else:
        t.right = HuffmanNode()
        t.right.number = n.r_data
    t.number = i
    return t
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that the list represents a tree in postorder.

    Note that the parameter root_index is useless because since the
    tree is represented in postorder, the root node is the last
    element of node_lst.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12),\
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)), HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """
    # we create a list of HuffmanNode nodes which are the nodes of the tree.
    huffman_nodes = []
    root_index += 1

    # since we have a postorder traversal, children are always generated before
    # parents. So, we go through the read nodes and transform them to internal
    # huffman nodes. We don't need to check if children have
    # already been generated, we know they were. We add the nodes to the
    # huffman nodes list in a postorder way, meaning that if we were to create
    # the list by traversing the huffman tree in postorder, we would obtain
    # the same list.
    for index, read_node in enumerate(node_lst):
        # create the internal node
        node = HuffmanNode(None, None, None)

        # Right child
        # if right child is a leaf
        if read_node.r_type == 0:
            # r_data is the symbol of the right child
            node.right = HuffmanNode(read_node.r_data, None, None)
        else:
            # right child is an internal leaf
            # index of right child is index - 1
            # we know (because postorder) that it has already
            # been created.
            node.right = huffman_nodes[index - 1]

        # Left child
        # if the left child is a leaf
        if read_node.l_type == 0:
            # l_data is the symbol of the left child
            node.left = HuffmanNode(read_node.l_data, None, None)
        else:
            # left child is an internal leaf. We must find its index.
            # if right child is a leaf then left index = index - 1
            if read_node.r_type == 0:
                # left is not leaf and right is leaf
                node.left = huffman_nodes[index - 1]
            else:
                # left and right both are not leafs
                # index of left child = index - number of internal nodes in
                # right child tree - 1
                right_internal_nodes_count = internal_nodes_count(node.right)
                node.left = huffman_nodes[index - right_internal_nodes_count -
                                          1]

        # Add the current node to the list of nodes
        huffman_nodes.append(node)

    # At the end, the last element in the list of nodes
    # is the root of the huffman tree
    return huffman_nodes[-1]
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in the list.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> generate_tree_general(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)), HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
    """
    # root = ReadNode(1, left_node_index, 1, right_node_index)
    # we create a list of HuffmanNode nodes which are the nodes of the tree.
    # we initialize every element to None
    huffman_nodes = [None for _ in range(len(node_lst))]

    # We transform each ReadNode into an internal HuffmanNode, and we generate
    # the corresponding children
    for index, r_node in enumerate(node_lst):
        # enumerate(L) = [(index, L(index)]
        # we generate the huffman tree node whose number is index. It might have
        # already been generated by its parent so we check for that
        if huffman_nodes[index]:
            node = huffman_nodes[index]
        else:
            # we must generate it now
            node = HuffmanNode(None, None, None)
            # we set its number to index
            node.number = index
            # we add it to the list of huffman tree nodes, at index position
            huffman_nodes[index] = node

        # we create the left child of the node depending
        # on whether it's a leaf or not
        if r_node.l_type == 0:
            # it's a leaf node. l_data is the symbol if the left child
            child = HuffmanNode(r_node.l_data, None, None)
        else:
            # internal node, we get it from the list of
            # huffman nodes or we create it.
            # l_data is the index (and number) of the child
            if huffman_nodes[r_node.l_data]:
                child = huffman_nodes[r_node.l_data]
            else:
                # we create the left child and add it to the list
                child = HuffmanNode(None, None, None)
                child.number = r_node.l_data
                huffman_nodes[r_node.l_data] = child
            # now we set the child as a left child of the node
        node.left = child

        # we do the same thing for the right child.
        # we create the right child of the node
        # depending on whether it's a leaf or not
        if r_node.r_type == 0:
            # it's a leaf node. r_data is the symbol if the right child
            child = HuffmanNode(r_node.r_data, None, None)
        else:
            # it's an internal node, we get it from the
            # list of huffman nodes or we create it.
            # r_data is the index (and number) of the child
            if huffman_nodes[r_node.r_data]:
                child = huffman_nodes[r_node.r_data]
            else:
                # we create the right child and add it to the list
                child = HuffmanNode(None, None, None)
                child.number = r_node.r_data
                huffman_nodes[r_node.r_data] = child
            # now we set the child as a right child of the node
        node.right = child

    # the root node of the huffman is at root_index of the huffman_nodes list
    return huffman_nodes[root_index]
예제 #19
0
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in the list.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> generate_tree_general(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None), \
HuffmanNode(12, None, None)), \
HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
    """
    def generate_from_readnote(node):
        """Return a HuffmanNode that is generated from ReadNote

        @param ReadNode node: a ReadNode
        @rtype: HuffmanNode
        >>>a = ReadNode(1, 5, 0, 7)
        >>>b = generate_from_readnote(a)
        >>>b
        HuffmanNode(None, HuffmanNode(None, None, None),
         HuffmanNode(7, None, None))
        """
        final = HuffmanNode()
        if node.l_type == 0:
            final.left = HuffmanNode(node.l_data)
        elif node.l_type == 1:
            final.left = HuffmanNode()
            final.left.number = node.l_data
        if node.r_type == 0:
            final.right = HuffmanNode(node.r_data)
        elif node.r_type == 1:
            final.right = HuffmanNode()
            final.right.number = node.r_data
        return final

    answer_g = generate_from_readnote(node_lst[root_index])
    node_lst.pop(root_index)

    def rebuild(lst_in, answer):
        """Return answer which is modified according to lst_in

        @param list[ReadNode] lst_in: a list of ReadNode objects
        @param HuffmanNode answer: a tree with only a root in it
        @rtype: HuffmanNode

        >>>list_haha = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12),
        ReadNode(1, 1, 1, 0)]
        >>>root_haha = HuffmanNode(None, HuffmanNode(None, None, None),
         HuffmanNode(None, None, None))
        >>>root_haha.left.number = 1
        >>>root_haha.right.number = 0
        >>>haha = rebuild(list_haha, root_haha)
        >>>haha
        HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None), \
HuffmanNode(12, None, None)), \
HuffmanNode(None, HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
        """
        if answer.left.number is None and answer.right.number is None:
            pass
        else:
            if answer.left.number is not None:
                answer.left = generate_from_readnote(
                    lst_in[answer.left.number])
                answer.left = rebuild(lst_in, answer.left)
            if answer.right.number is not None:
                answer.right = \
                    generate_from_readnote(lst_in[answer.right.number])
                answer.right = rebuild(lst_in, answer.right)
        return answer

    return rebuild(node_lst, answer_g)
예제 #20
0
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
예제 #21
0
파일: huffman.py 프로젝트: cicizh/Huffman
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in the list.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> tree_example = HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, \
    None, None), HuffmanNode(12, None, None)), HuffmanNode(None, \
    HuffmanNode(5, None, None), HuffmanNode(7, None, None)))
    >>> tree_example == generate_tree_general(lst, 2)
    True
    """
    if node_lst[root_index].l_type == 0 and node_lst[root_index].r_type == 0:
        node = HuffmanNode(None, HuffmanNode(node_lst[root_index].l_data),
                           HuffmanNode(node_lst[root_index].r_data))
    elif node_lst[root_index].l_type == 0 and node_lst[root_index].r_type == 1:
        node = HuffmanNode(None, HuffmanNode(node_lst[root_index].l_data),
                           generate_tree_general(node_lst,
                                                 node_lst[root_index].r_data))
    elif node_lst[root_index].l_type == 1 and node_lst[root_index].r_type == 0:
        node = HuffmanNode(None,
                           generate_tree_general(node_lst,
                                                 node_lst[root_index].l_data),
                           HuffmanNode(node_lst[root_index].r_data))
    else:
        node = HuffmanNode(None,
                           generate_tree_general(node_lst,
                                                 node_lst[root_index].l_data),
                           generate_tree_general(node_lst,
                                                 node_lst[root_index].r_data))
    node.number = root_index
    return node
"""
예제 #23
0
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that the list represents a tree in postorder.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), \
HuffmanNode(7, None, None)), \
HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """
    root_node_read = node_lst[root_index]
    root = HuffmanNode()
    # if the root node has two leaves.
    if (root_node_read.l_type, root_node_read.r_type) == (0, 0):
        root.left = HuffmanNode(root_node_read.l_data)
        root.right = HuffmanNode(root_node_read.r_data)
        return root
    else:
        # if root node has left leaf and right subtree.
        if (root_node_read.l_type, root_node_read.r_type) == (0, 1):
            root.left = HuffmanNode(root_node_read.l_data)
            root.right = generate_tree_postorder(node_lst, root_index - 1)
        # if root node has right leaf and left subtree.
        if (root_node_read.l_type, root_node_read.r_type) == (1, 0):
            root.left = generate_tree_postorder(node_lst, root_index - 1)
            root.right = HuffmanNode(root_node_read.r_data)
        # if both left and right have subtrees.
        if (root_node_read.l_type, root_node_read.r_type) == (1, 1):
            # construct the right subtree.
            root.right = generate_tree_postorder(node_lst, root_index - 1)
            # find the root index of the left subtree.
            left_root_index = root_index - count_internal(root.right) - 1
            root.left = generate_tree_postorder(node_lst, left_root_index)
        return root
예제 #24
0
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that the list represents a tree in postorder.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), \
HuffmanNode(7, None, None)), \
HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """
    result = HuffmanNode()
    c = (root_index + 1) - (count_internal(node_lst) + 1)
    if node_lst[root_index].l_type == 0:
        if node_lst[root_index].r_type == 0:
            lsymbol = node_lst[root_index].l_data
            rsymbol = node_lst[root_index].r_data
            result.left = HuffmanNode(lsymbol, None, None)
            result.right = HuffmanNode(rsymbol, None, None)
    if node_lst[root_index].l_type != 0:
        if node_lst[root_index].r_type == 0:
            result.left = generate_tree_postorder(node_lst[0:-2],
                                                  node_lst[root_index].l_data)
            rsymbol = node_lst[-2].r_data
            result.right = HuffmanNode(rsymbol, None, None)
    if node_lst[root_index].r_type != 0:
        if node_lst[root_index].l_type == 0:
            lsymbol = node_lst[0].l_data
            result.left = HuffmanNode(lsymbol, None, None)
            result.right = generate_tree_postorder(node_lst[1:-1],
                                                   node_lst[root_index].r_data)
    if node_lst[root_index].r_type != 0:
        if node_lst[root_index].l_type != 0:
            result.right = generate_tree_postorder(node_lst[c:-1],
                                                   node_lst[root_index].r_data)
            result.left = generate_tree_postorder(node_lst[0:c],
                                                  node_lst[root_index].l_data)
    return result
예제 #25
0
 def duplicate_node(node):
     """takes huffman nodes, and makes it into a single node
     @param HuffmanNode node: a HuffmanNode node
     rtype: a HuffmanNode with its left and right duplicates of itself
     """
     return HuffmanNode(None, node.left, node.right)
예제 #26
0
def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in the list.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
    >>> a = generate_tree_general(lst, 2)
    >>> b = HuffmanNode(None, HuffmanNode(None, HuffmanNode(10, None, None),\
    HuffmanNode(12, None, None)), HuffmanNode(None, HuffmanNode(5, None,\
    None), HuffmanNode(7, None, None)))  # made changes to these examples
    >>> a == b
    True
    """
    a = HuffmanNode()
    if node_lst[root_index].l_type == 0 and node_lst[root_index].r_type == 0:
        a = HuffmanNode(None, HuffmanNode(node_lst[root_index].l_data),
                        HuffmanNode(node_lst[root_index].r_data))
        return a
    if node_lst[root_index].l_type == 0:
        a.left = HuffmanNode(node_lst[root_index].l_data)
    elif node_lst[root_index].l_type == 1:  # can't convert to node here
        # because the function already returns a node
        a.left = generate_tree_general(
            node_lst,
            node_lst[  # recursion
                root_index].l_data)
    if node_lst[root_index].r_type == 0:  # base  case-ish
        a.right = HuffmanNode(node_lst[root_index].r_data)
    elif node_lst[root_index].r_type == 1:  # same reason
        a.right = generate_tree_general(
            node_lst,
            node_lst[  # recursion
                root_index].r_data)
    return a
예제 #27
0
    freq = make_freq_dict(text)
    tree = huffman_tree(freq)
    codes = get_codes(tree)
    number_nodes(tree)
    print("Bits per symbol:", avg_length(tree, freq))
    result = (num_nodes_to_bytes(tree) + tree_to_bytes(tree) +
              size_to_bytes(len(text)))
    result += generate_compressed(text, codes)
    with open(out_file, "wb") as f2:
        f2.write(result)


# ====================
# Functions for decompression
HuffmanNode(
    None, HuffmanNode(101, None, None),
    HuffmanNode(None, HuffmanNode(115, None, None),
                HuffmanNode(110, None, None)))


def generate_tree_general(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes nothing about the order of the nodes in node_lst.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in 'node_lst'
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 1, 1, 0)]
예제 #28
0
    def create_tree(node_lst1, root_index1):
        """
        Returns the root of the tree rooted at root_index, but this function
        uses n in for cases in which the tree has not been generated and we
        still need to create other nodes for the tree on the left. By using a
        list n, and continuoulsy appending -1 in each of the cases until we
        reach the leftmost node, we go deeper and deeper into the tree and can
        traverse it easily. While for the right side, if there are still nodes
        left to create, we send root_index - 1 for each recursion until we reach
        the highest leftmost node.

        @param list[ReadNode] node_lst1: a list of ReadNode objects
        @param int root_index1: index in the node list
        @rtype: HuffmanNode
        """
        copy_list = node_lst1.copy()
        a = HuffmanNode()
        if node_lst1[root_index1].l_type == 0 and node_lst1[root_index1].r_type\
                == 0:
            a = HuffmanNode(None, HuffmanNode(node_lst1[root_index1].l_data),
                            HuffmanNode(node_lst1[root_index1].r_data))
            return a
        if node_lst1[root_index1].l_type == 0:
            a.left = HuffmanNode(node_lst1[root_index1].l_data)
        elif node_lst1[root_index1].l_type == 1:
            n.append(-1)  # to go deeper
            a.left = create_tree(copy_list, sum(n))  # sum to get int

        if node_lst1[root_index1].r_type == 0:  # base  case-ish
            a.right = HuffmanNode(node_lst[root_index1].r_data)
        elif node_lst1[root_index1].r_type == 1:  # same reason
            # because right uppermost create_treeis always to the left of the
            # root in postorder
            a.right = create_tree(copy_list, root_index1 - 1)
        return a
def generate_tree_postorder(node_lst, root_index):
    """ Return the root of the Huffman tree corresponding
    to node_lst[root_index].

    The function assumes that the list represents a tree in postorder.

    @param list[ReadNode] node_lst: a list of ReadNode objects
    @param int root_index: index in the node list
    @rtype: HuffmanNode

    >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
    ReadNode(1, 0, 1, 0)]
    >>> generate_tree_postorder(lst, 2)
    HuffmanNode(None, HuffmanNode(None, HuffmanNode(5, None, None), \
    HuffmanNode(7, None, None)), \
    HuffmanNode(None, HuffmanNode(10, None, None), HuffmanNode(12, None, None)))
    """

    # todo
    def depth(node_lst, root_index):
        """ Returns the depth of each subtree.

        The function assumes that the list represents a tree in postorder.

        @param list[ReadNode] node_lst: a list of ReadNode objects
        @param int root_index: index in the node list
        @rtype: int

        >>> lst = [ReadNode(0, 5, 0, 7), ReadNode(0, 10, 0, 12), \
        ReadNode(1, 0, 1, 0)]
        >>> depth(lst, 2)
        2
        """
        root = node_lst[root_index]
        result = 1
        i = 0

        if root.r_type:
            i = depth(node_lst, root_index - 1)
            result += i

        if root.l_type:
            result += depth(node_lst, root_index - i - 1)

        return result

    root = node_lst[root_index]
    tree = HuffmanNode(None)

    if root.r_type == 0:
        tree.right = HuffmanNode(root.r_data)
        r_count = 0
    else:
        tree.right = generate_tree_general(node_lst, root_index - 1)
        r_count = depth(node_lst, root_index - 1)

    if root.l_type == 0:
        tree.left = HuffmanNode(root.l_data)
    else:
        tree.left = generate_tree_general(node_lst, root_index - r_count - \
                                          1)
    return tree
예제 #30
0
    l = [[2, 3], [6, 7], [3, 34], [24, 64], [1, 43]]
    l = sorted(l, key=getkey)
    print(l)
    """

    """ Test using multiple arguements in for loop
    d = make_freq_dict(bytes([65, 66, 67, 66]))
    for k, v in d.items():
        print(k, 'corresponds to', v)
    """

    # Testing get_codes()
    freq = {2: 6, 3: 4, 4: 13, 5: 17}
    t = huffman_tree(freq)
    d = get_codes(t)
    print(t)
    print(d)

    freqs = {'a': 2}
    d = HuffmanNode()
    print(d)

    print(get_codes(d))

    print(bytes([65, 66, 67, 66]))

    left = HuffmanNode(None, HuffmanNode(3), HuffmanNode(2))
    right = HuffmanNode(None, HuffmanNode(9), HuffmanNode(10))
    tree = HuffmanNode(None, left, right)
    number_nodes(tree)