首页 > 其他分享 >二叉树可视化 - 哈夫曼树

二叉树可视化 - 哈夫曼树

时间:2022-11-18 15:24:55浏览次数:59  
标签:node matrix 哈夫曼 self width 可视化 二叉树 ._ left

哈夫曼树可视化

import matplotlib.pyplot as plt


class Tree:
    def __init__(self, weight=None, left=None, right=None):
        self.weight = weight
        self.left = left
        self.right = right
        self.is_red = False

    def get_height(self):  # 返回树高度,未优化算法应该比较慢
        layers = [self]
        layer_count = 0
        while layers:
            layer_count += 1
            new_list = []
            for node in layers:
                if node.left:
                    new_list.append(node.left)
                if node.right:
                    new_list.append(node.right)
            layers = new_list
        return layer_count

    def visualize(self, axis='off'):
        ''' 可视化树结构

            基本算法: 将树状结构映射到二维矩阵中,
            如果节点左右下方有节点则把该节点加入到矩阵中的坐标中,
            如节点(x,y)左下方有节点则把节点放入(x+offset,y+1)
            offset为x坐标偏移量,
            offset = 2**(len(matrix)-y-2)
        '''
        FONT_SIZE = 16
        NODE_SIZE_SCALE = 1.5
        figure, axes = plt.subplots(figsize=(8, 6), dpi=80)
        height = self.get_height()
        width_ = 2 ** (height - 1)
        width = 2 * width_ + 1
        matrix = [[[] for x in range(width)] for y in range(height)]

        matrix[0][width_] = self  # put head in the middle position

        for y in range(len(matrix)):
            for x in range(len(matrix[y])):
                node = matrix[y][x]
                if node:
                    x1, y1 = (1 / width) * (x + 0.5), 1 - (1 / height) * y - 0.2
                    axes.text(x1, y1, str(node.weight), color='white', fontsize=FONT_SIZE)
                    offset = 2 ** (len(matrix) - y - 2)

                    if node.left:
                        matrix[y + 1][x - offset] = node.left
                        x2, y2 = (1 / width) * (x - offset + 0.5), 1 - (1 / height) * (y + 1) - 0.2
                        line = mlines.Line2D([x1, x2], [y1, y2], zorder=-1)
                        axes.add_line(line)
                    if node.right:
                        matrix[y + 1][x + offset] = node.right
                        x2, y2 = (1 / width) * (x + offset + 0.5), 1 - (1 / height) * (y + 1) - 0.2
                        line = mlines.Line2D([x1, x2], [y1, y2], zorder=-1)
                        axes.add_line(line)
                    cc = plt.Circle(((1 / width) * (x + 0.5), 1 - (1 / height) * y - 0.2),
                                    1 / width / 2 * NODE_SIZE_SCALE,
                                    color=('r' if node.is_red else 'black'))
                    axes.set_aspect(1)
                    axes.add_artist(cc, )

        plt.axis(axis)
        plt.show()


class HuffmanTree:
    """哈夫曼树(huffmanTree)

    构建方法:
        将几点根据权重大小放到最小堆中,先从做小堆中取出两个最小元素,构成一棵树,根节点权重为两子树的和。然后将根节点插入堆中,依次上边操作,
        共计操作数据长度-1次,此时堆中只有一个元素,就是哈夫曼树的根节点。WPL等于根节点的权重值。
    """
    def __init__(self, element: list):
        self._element = element
        self._size = len(element) + 1
        self._used = 0
        self._case = [None for _ in range(self._size)]

    def _is_full(self):
        return self._used > self._size

    def insert(self, root: Tree):
        """往堆中插入元素"""
        if self._is_full():
            return 'is full'

        self._used += 1
        add_node = self._used
        father = self._used // 2
        while father:
            if root.weight > self._case[father].weight:
                break
            self._case[add_node] = self._case[father]
            add_node = father
            father //= 2

        self._case[add_node] = root

    def delete(self):
        """从堆中删除元素"""
        if self._used == 0:
            return 'is empty'

        root = 1
        res = self._case[root]
        # node = self._used
        while True:
            left_son = root * 2
            right_son = left_son + 1

            if left_son < self._used and self._case[left_son].weight <= self._case[right_son].weight and self._case[
                left_son].weight < \
                    self._case[self._used].weight:
                self._case[root] = self._case[left_son]
                root = left_son
            elif right_son < self._used and self._case[right_son].weight <= self._case[left_son].weight and self._case[
                right_son].weight < \
                    self._case[self._used].weight:
                self._case[root] = self._case[right_son]
                root = right_son
            else:
                break

        self._case[root] = self._case[self._used]
        self._case[self._used] = None
        self._used -= 1
        return res

    def create(self):
        """构建哈夫曼树"""
        for i in self._element:
            tree = Tree(i)
            self.insert(tree)

        for _ in range(self._size - 2):
            left = self.delete()
            right = self.delete()
            tree = Tree(left.weight + right.weight, left, right)
            self.insert(tree)

        tree = self.delete()
        return tree


if __name__ == '__main__':
    # heap = Heap()
    a = [3, 1, 4, 5, 6]
    huff = HuffmanTree(a)
    r = huff.create()
    # t = Tree()
    r.visualize()  # 可视化树结构

效果展示
image

标签:node,matrix,哈夫曼,self,width,可视化,二叉树,._,left
From: https://www.cnblogs.com/yimeimanong/p/16903337.html

相关文章

  • 低代码可视化开发平台SovitJs功能更新速递
    SovitJS系列产品近期又做了不少的功能优化升级工作,以下将主要优化升级的内容列出供用户参考。数据源功能升级1.项目面板中增加数据源管理入口,方便快速管理数据源以及协同操......
  • 114. 二叉树展开为链表 -----
    给你二叉树的根结点root,请你将它展开为一个单链表:展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。展开后的单链......
  • LSTM模型可视化讲解
    昨夜突然刷到一条讲解LSTM的推送,其中一张图让我彻底明白了LSTM的输入模式。下面放链接:可视化理解LSTM(qq.com)[LSTM模型结构的可视化-知乎(zhihu.com)](......
  • 十六、二叉树(二叉链表)遍历算法
    一、二叉树的遍历遍历二叉树(Traversingbinarytree)是指按某条搜索路径巡访树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。先序遍历(根左右)中序遍历......
  • 【树】之二叉树(C语言)(含图解)
    树&二叉树​​树​​​​树的概念及结构​​​​树的概念​​​​树的要求​​​​树的表示​​​​现实应用​​​​二叉树​​​​概念​​​​特殊的二叉树​​​​注意......
  • NowCoder刷题(1)【树】二叉树的遍历(含图解)
    二叉树的遍历(IO型)二叉树遍历_牛客题霸_牛客网(nowcoder.com)题目描述如图所示的这棵树前序输出结果为A-B-D-#-#-E-#-#-C-#-#还原过程示例1示例2——前序遍历还原代码实现......
  • 关于二叉树,你应该了解这些。(二叉树的理论基础)
    推荐视频——关于二叉树,你该了解这些!|二叉树理论基础一网打尽,二叉树的种类、二叉树的存储方式、二叉树节点定义、二叉树的遍历顺序_哔哩哔哩(゜-゜)つロ干杯~-bilibili我......
  • 利用数组构建二叉树(随笔)
    做leetcode的时候,看到示例,突然想自己构建一颗树。。随即自己写了尝试写了一个方法(比较随意)测试用例://example-1[2,1,3]//example-2[2,null,3]//example-3[5,3......
  • 数据库可视化工具分享 (DBeaver)
    前提:最近公司下发通知,所有开发人员必须卸载Navicat数据库可视化工具,不知道兄弟们有没有在使用的,可能现在的反应跟我一样,一脸懵逼,Navicat为什么不能使用呢?有事没事找度......
  • 案例解析:电商销售数据可视化管理系统
    电商行业的快速发展得益于数字化经济的快速发展,大家纷纷借助大数据、5G等技术将自己的企业精细化管理。 电商销售数据可视化操作一般分为4步:①了解拥有的数据②确定想......