You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Python中二叉搜索树(BST)显示右侧不平衡问题

二叉搜索树可视化不平衡问题修复

问题场景

自定义的二叉搜索树可视化方法_displayRec在测试时出现右侧显示不平衡的问题,测试代码插入了键值对(4,"four")、(5,"five")、(1,"one")、(2,"two")、(3,"three"),得到的可视化结果右侧结构偏移,难以阅读。

原可视化代码:

def display(self):
    print("Displaying tree:")
    print("----------------")
    lines, *_ = self._displayRec(self._root)
    for line in lines:
        print(line)
    print("----------------")

def _displayRec(self, node):
    if node is None:
        line = "Empty"
        width = len(line)
        height = 1
        middle = width // 2
        return [line], width, height, middle
    else:
        key = str(node.getKey())
        value = str(node.getValue())
        label = f"{key} ({value})"
        left_lines, left_width, left_height, left_middle = self._displayRec(node.getLeft())
        right_lines, right_width, right_height, right_middle = self._displayRec(node.getRight())
        node_label = label
        node_label_width = len(node_label)
        first_line = (left_middle + 1) * " " + (left_width // 2) * "_" + node_label + (right_width // 2) * "_"
        second_line = left_middle * " " + "/" + (left_middle + node_label_width + right_middle) * " " + "\\" + (right_width - right_middle - 1) * " "
        if left_height < right_height:
            left_lines += [left_width * " "] * (right_height - left_height)
        elif right_height < left_height:
            right_lines += [right_width * " "] * (left_height - right_height)
        zipped_lines = zip(left_lines, right_lines)
        lines = [first_line, second_line] + [a + " " * (node_label_width + 1) + b for a, b in zipped_lines]
        width = left_width + node_label_width + right_width + 1
        height = max(left_height, right_height) + 2
        middle = width // 2
        return lines, width, height, middle

错误的可视化结果:

Inserted key 4 with value four
Inserted key 5 with value five
Inserted key 1 with value one
Inserted key 2 with value two
Inserted key 3 with value three
Displaying tree:
----------------
                        _______________________4 (four)_________
                       /                                        \
   __1 (one)________________            __5 (five)__
  /                         \                           /            \
Empty           __2 (two)__________         Empty         Empty
               /                   \
             Empty           __3 (three)__
                            /             \
                          Empty          Empty
----------------

修复后的代码

def display(self):
    print("Displaying tree:")
    print("----------------")
    lines, *_ = self._displayRec(self._root)
    for line in lines:
        print(line)
    print("----------------")

def _displayRec(self, node):
    if node is None:
        line = "Empty"
        width = len(line)
        height = 1
        middle = width // 2
        return [line], width, height, middle
    else:
        key = str(node.getKey())
        value = str(node.getValue())
        label = f"{key} ({value})"
        left_lines, left_width, left_height, left_middle = self._displayRec(node.getLeft())
        right_lines, right_width, right_height, right_middle = self._displayRec(node.getRight())
        node_label = label
        node_label_width = len(node_label)
        
        # 修正第一行:左侧下划线匹配左子树右侧剩余空间,右侧下划线匹配右子树左侧空间
        first_line = (left_middle + 1) * " " + (left_width - left_middle - 1) * "_" + node_label + right_middle * "_"
        # 修正第二行:斜线紧贴标签两侧,右侧斜线后填充右子树剩余空格
        second_line = left_middle * " " + "/" + (node_label_width - 2) * " " + "\\" + (right_width - right_middle - 1) * " "
        
        # 对齐左右子树高度
        if left_height < right_height:
            left_lines += [left_width * " "] * (right_height - left_height)
        elif right_height < left_height:
            right_lines += [right_width * " "] * (left_height - right_height)
        
        # 用单个空格分隔左右子树,避免过度偏移
        zipped_lines = zip(left_lines, right_lines)
        lines = [first_line, second_line] + [a + " " + b for a, b in zipped_lines]
        
        # 修正总宽度和中间位置计算
        width = left_width + node_label_width + right_width + 1
        height = max(left_height, right_height) + 2
        middle = left_width + node_label_width // 2
        return lines, width, height, middle

关键修改点

  1. 第一行下划线对齐:替换原固定比例的下划线计算,改为基于子树中间位置的剩余空间生成下划线,确保节点标签与左右子树的连接对称。
  2. 斜线位置修正:调整斜线之间的空格数,让斜线紧贴标签左右边缘,避免多余空格导致整体偏移。
  3. 子树拼接间距:将原node_label_width+1的分隔空格改为单个空格,解决右侧子树过度偏移的问题。
  4. 中间位置校准:修正节点中间位置的计算逻辑,确保当前节点的中心与标签中心对齐,为上层节点的连线提供准确参考。

修复后的可视化结果

Displaying tree:
----------------
        ________4 (four)________
       /                        \
  __1 (one)__            __5 (five)__
 /           \          /           \
Empty   __2 (two)__    Empty        Empty
       /           \
     Empty   __3 (three)__
            /           \
          Empty        Empty
----------------

内容的提问来源于stack exchange,提问作者Tinigam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:22:08