思路

C++实在是弄不懂

代码

from typing import List, Optional

class Node:
    """
    结点
    """
    def __init__(self):
        self.name: Optional[str] = None
        self.weight: Optional[int] = None
        self.left_child: Optional[Node] = None
        self.right_child: Optional[Node] = None
        self.parent: Optional[Node] = None

class NodeCode:
    """
    结点的编码
    """
    def __init__(self, name: str, code: str):
        self.name = name
        self.code = code

    def __str__(self):
        return f"{self.name}:{self.code}"

class HaffumanTreeCode:
    """
    哈夫曼树的编码
    """
    def __init__(self):
        self.code_list: List[NodeCode] = []

    def append(self, code: NodeCode):
        self.code_list.append(code)

    def code(self, massage: str):
        """
        针对编码表编码
        :param massage: 需要编码的信息
        :return:
        """
        code = ""
        for i in massage:
            for n in self.code_list:
                if n.name == i:
                    code += n.code
                    break
            # raise ValueError(f"'{i}'不存在")
        return code

    def decode(self, code: str):
        """
        针对编码表解码
        :param code:需要解码的哈夫曼码
        :return:
        """
        out = ""
        i = 0
        while code:
            code_need_match = code[0:i+1]
            for n in self.code_list:
                if n.code == code_need_match:
                    out += n.name
                    code = code[i+1:]
                    i = 0
                    break
            i += 1
        return out

    def __str__(self):
        """
        打印
        :return:
        """
        out = ""
        for i in self.code_list:
            out += i.__str__() + "\n"
        return out.strip()

class HaffumanTree:
    """
    哈夫曼树
    """
    def __init__(self):
        self.root = Node()
        self.nodes: List[Node] = []
        self.nodes_raw: List[Node] = []
        self.codes: HaffumanTreeCode = HaffumanTreeCode()

    def inser(self, newnode: Node):
        for i in range(len(self.nodes)):
            if self.nodes[i].weight < newnode.weight:
                self.nodes.insert(i, newnode)
                return
        self.nodes.append(newnode)

    def build_tree(self, name_list: List[str], weight_list: List[int]):
        """
        创建哈夫曼树
        :param name_list: 字符列表
        :param weight_list: 权重列表
        :return:
        """
        # 队每个字符生成结点
        while len(name_list) > 0:
            max_weight = max(weight_list)
            max_index = weight_list.index(max_weight)
            max_name = name_list[max_index]
            newnode = Node()
            newnode.name = max_name
            newnode.weight = max_weight
            self.nodes.append(newnode)
            name_list.remove(max_name)
            weight_list.remove(max_weight)

        # 保存源结点
        self.nodes_raw = self.nodes[:]

        # 创建新结点并生成树
        while len(self.nodes) > 2:
            left = self.nodes.pop()
            right = self.nodes.pop()
            newnode = Node()
            newnode.weight = left.weight + right.weight
            newnode.left_child = left
            newnode.right_child = right
            left.parent = newnode
            right.parent = newnode
            # 根据权重插入
            self.inser(newnode)

        left = self.nodes.pop()
        right = self.nodes.pop()
        self.root.weight = left.weight + right.weight
        self.root.left_child = left
        self.root.right_child = right
        left.parent = self.root
        right.parent = self.root

    def make_code(self):
        """
        生成编码表
        :return:
        """
        while len(self.nodes_raw):
            node = self.nodes_raw.pop()
            name = node.name
            code = ""
            while node.parent != self.root:
                parent = node.parent
                if parent.left_child == node:
                    code = "0" + code
                elif parent.right_child == node:
                    code = "1" + code
                node = parent
            if self.root.left_child == node:
                code = "0" + code
            elif self.root.right_child == node:
                code = "1" + code
            self.codes.append(NodeCode(name, code))

    def decode(self, code: str):
        return self.codes.decode(code)

    def code(self, massage: str):
        return self.codes.code(massage)

if __name__ == '__main__':
    h = HaffumanTree()
    name_list = ["a", "b", "c", "d", "e"]
    wight_list = [5, 11, 6, 21, 19]
    h.build_tree(name_list, wight_list)
    h.make_code()
    print(f"编码表:\n{h.codes}")
    print(f'bcacce编码为:{h.code("bcacce")}')
    print(f'01001000001001解码为: {h.decode("0100100000100110")}')