Python 实现列表与二叉树相互转换并打印二叉树封装类-详细注释+完美对齐
# MyBinaryTree.py # Python 实现列表与二叉树相互转换并打印二叉树封装类-详细注释+完美对齐 # by: ybmj@vip.163.com, QQ: 153248043, blog: https://www.cnblogs.com/ybmj/ from binarytree import build import random class MyBinaryTree: lst = [] # 二叉树列表 lay_list = [] # 二叉树层列表 node_list = [] # 二叉树节点列表 def __init__(self, lst=[]): MyBinaryTree.lst = lst class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right # 从二叉树列表得到二叉树层列表 def getLaylist(self): if MyBinaryTree.lay_list: return MyBinaryTree.lay_list if not MyBinaryTree.lst: return [] # 判断列表为空不能用 is None,必须用 not _list。判断变量为空才能用 is None lay = 0 # 层数 loc = 0 # 节点列表当前位置 len_all = len(MyBinaryTree.lst) # 整个列表的长度 while len_all > 0: len_lay = pow(2, lay) # 该层列表的长度,每层的长度为 2^lay,2^0、2^1、2^2、2^3、... MyBinaryTree.lay_list.append(MyBinaryTree.lst[loc:(loc + len_lay)]) # 从 _list 切片得到该层的元素列表,添加到 lay_list 中 loc += len_lay len_all -= len_lay lay += 1 return MyBinaryTree.lay_list # 从二叉树层列表得到二叉树节点列表 def getNodelist(self): if MyBinaryTree.node_list: return MyBinaryTree.node_list if not MyBinaryTree.lay_list: MyBinaryTree.lay_list = self.getLaylist() if not MyBinaryTree.lay_list: return [] for i in range(len(MyBinaryTree.lay_list)): # 对 lay_list 的节点(每个节点元素都为列表)进行循环遍历,用列表中的每个元素构建TreeNode添加到node_list中 for j in range(len(MyBinaryTree.lay_list[i])): # 转换层列表为:[[5], [2, 9], [10, 1, 10, 5], [0, 9, 1]] MyBinaryTree.node_list.append( MyBinaryTree.TreeNode(MyBinaryTree.lay_list[i][j])) # 将列表索引 j 元素构建TreeNode添加到node_list中 # 为上一层的父节点 TreeNode 元素添加 left、或right 值 # if lay_list[tail][j] and lay > 0: # 在 python 中0、空都为假,非零为真,所以这样将导致 lay_list[tail][j] 为 0 时没能填充 if MyBinaryTree.lay_list[i][j] is not None and i > 0: # 必须改为这样,才能避免 lay_list[tail][j] 为 0 时没能填充 if j % 2 == 0: MyBinaryTree.node_list[pow(2, i - 1) - 1 + j // 2].left = MyBinaryTree.node_list[-1] else: MyBinaryTree.node_list[pow(2, i - 1) - 1 + j // 2].right = MyBinaryTree.node_list[-1] return MyBinaryTree.node_list # 从二叉树节点列表得到二叉树列表 def getListFromTree(self): if not MyBinaryTree.node_list: MyBinaryTree.node_list = self.getNodelist() if not MyBinaryTree.node_list: return [] # root 为二叉树该层的父节点,i 为该层节点数量,_list 为输出列表 def treeRecursion(root, i, _list): if root is None: return len1 = len(_list) if len1 <= i: # 填充该层节点的占位元素 for j in range(i - len1 + 1): _list.append(None) _list[i] = root.val # 填入该层的父节点元素 treeRecursion(root.left, 2 * i, _list) # 递归处理该层的左子树 treeRecursion(root.right, 2 * i + 1, _list) # 递归处理该层右子树 _list = [] treeRecursion(MyBinaryTree.node_list[0], 1, _list) # 获得中间二叉树列表:[None, x1, x2, ...] while _list and _list[0] is None: # 删除中间二叉树列表头部的空元素,得到:[x1, x2, ...] del (_list[0]) return _list # 打印二叉树节点列表 def printNodeList(self, node_list=[]): if not node_list: node_list = self.getNodelist() def getNodeName(node, name="Node"): return "None" if node is None or node.val is None else name + "{:0>2d}".format(node.val) print("node:".ljust(7), "val".ljust(5), "left".ljust(7), "right") # 打印节点的字段名 for node in range(len(node_list)): print(getNodeName(node_list[node]).ljust(6), end=": ") # 打印节点的名称 print((getNodeName(node_list[node], "") + ", ").ljust(6), (getNodeName(node_list[node].left) + ", ").ljust(8), getNodeName(node_list[node].right), sep='') # 打印节点的 val、left、right # 测试函数 def test_binarytree(list1): mytree = MyBinaryTree(list1) list2 = mytree.getListFromTree() print("原来的二叉树列表为:{}".format(list1)) print("转换后二叉树列表为:{}".format(list2)) print("转换前后的二叉树列表是否相等:{}".format(list1 == list2)) print("二叉树的层列表为:{}".format(mytree.getLaylist())) print("\n二叉树节点列表为(完美对齐):") mytree.printNodeList(mytree.getNodelist()) print("\n原来的列表转换为二叉树:{}".format(build(list1))) print("转换后的列表再转回二叉树:{}".format(build(list2))) if __name__ == "__main__": list1 = [0, 1, 2, 3, 4, 5, 6, None, 7, None, 9, None, None, 10, ] # 一般二叉树 # list1 = [i for i in range(20)] # 完全二叉树 # list1 = [random.randint(0, 99) for i in range(20)] # 完全二叉树 test_binarytree(list1) # S:\PythonProject\pyTest01\venv\Scripts\python.exe S:/PythonProject/pyTest01/main.py # 原来的二叉树列表为:[0, 1, 2, 3, 4, 5, 6, None, 7, None, 9, None, None, 10] # 转换后二叉树列表为:[0, 1, 2, 3, 4, 5, 6, None, 7, None, 9, None, None, 10] # 转换前后的二叉树列表是否相等:True # 二叉树的层列表为:[[0], [1, 2], [3, 4, 5, 6], [None, 7, None, 9, None, None, 10]] # # 二叉树节点列表为(完美对齐): # node: val left right # Node00: 00, Node01, Node02 # Node01: 01, Node03, Node04 # Node02: 02, Node05, Node06 # Node03: 03, None, Node07 # Node04: 04, None, Node09 # Node05: 05, None, None # Node06: 06, Node10, None # None : None, None, None # Node07: 07, None, None # None : None, None, None # Node09: 09, None, None # None : None, None, None # None : None, None, None # Node10: 10, None, None # # 原来的列表转换为二叉树: # ____0__ # / \ # __1 2___ # / \ / \ # 3 4 5 _6 # \ \ / # 7 9 10 # # 转换后的列表再转回二叉树: # ____0__ # / \ # __1 2___ # / \ / \ # 3 4 5 _6 # \ \ / # 7 9 10 # # # 进程已结束,退出代码0