Python实现普通二叉树

2023-11-05

Python实现普通二叉树

二叉树是每个节点最多有两个子树的树结构,本文使用Python来实现普通的二叉树。

关于二叉树的介绍,可以参考:https://blog.csdn.net/weixin_43790276/article/details/104737870

一、实现节点类

所有树结构都是由一个一个的节点构成的,本文使用链式的方式来实现二叉树,所以先实现一个节点类。

# coding=utf-8
class Node(object):
    """节点类"""
    def __init__(self, data, left_child=None, right_child=None):
        self.data = data
        self.parent = None
        self.left_child = left_child
        self.right_child = right_child

在二叉树中添加节点时,要先创建节点,有了节点类,实例化一个节点类的实例即可,节点初始化时是一个孤立的节点,指向的父节点、左子节点、右子节点都为空。将节点“挂”到树上(添加到树中)后,才属于树的一部分。

二、实现二叉树类

实现一个二叉树的类 BinaryTree ,创建二叉树时,实例化一个 BinaryTree 类的实例即可。

class BinaryTree(object):
    """二叉树类"""
    def __init__(self):
        self.__root = None
        self.prefix_branch = '├'
        self.prefix_trunk = '|'
        self.prefix_leaf = '└'
        self.prefix_empty = ''
        self.prefix_left = '─L─'
        self.prefix_right = '─R─'

    def is_empty(self):
        return not self.__root

    @property
    def root(self):
        return self.__root

    @root.setter
    def root(self, data):
        self.__root = Node(data)

    def show_tree(self):
        if self.is_empty():
            print('空二叉树')
            return
        print('-' * 20)
        print(self.__root.data)
        self.__print_tree(self.__root)
        print('-' * 20)

    def __print_tree(self, node, prefix=None):
        if prefix is None:
            prefix, prefix_left_child = '', ''
        else:
            prefix = prefix.replace(self.prefix_branch, self.prefix_trunk)
            prefix = prefix.replace(self.prefix_leaf, self.prefix_empty)
            prefix_left_child = prefix.replace(self.prefix_leaf, self.prefix_empty)
        if self.has_child(node):
            if node.right_child is not None:
                print(prefix + self.prefix_branch + self.prefix_right + str(node.right_child.data))
                if self.has_child(node.right_child):
                    self.__print_tree(node.right_child, prefix + self.prefix_branch + ' ')
            else:
                print(prefix + self.prefix_branch + self.prefix_right)
            if node.left_child is not None:
                print(prefix + self.prefix_leaf + self.prefix_left + str(node.left_child.data))
                if self.has_child(node.left_child):
                    prefix_left_child += '  '
                    self.__print_tree(node.left_child, self.prefix_leaf + prefix_left_child)
            else:
                print(prefix + self.prefix_leaf + self.prefix_left)

    def has_child(self, node):
        return node.left_child is not None or node.right_child is not None

    def __str__(self):
        return str(self.__class__)

一棵二叉树,只要先找到树的根节点(Root),就可以依次根据节点的父子关系找到所有节点,所以初始化一棵二叉树时,只要先指向树的根节点即可,在没有添加节点到二叉树中时,树是一棵空二叉树,树的根指向为空。

在初始化二叉树时,树的根设置为私有属性,这样做是有必要的,保证根节点的稳定。但是又需要通过实例对象来操作树的根,所以使用 @property 加 @root.setter 提供一对方法供实例对象使用,可以获取或设置二叉树的根节点。

同时,还实现了判断二叉树是否为空的 is_empty() 方法和按树形结构打印二叉树的 show_tree() 方法,在实现完全二叉树的另一篇文章里面有说明。可以参考:https://blog.csdn.net/weixin_43790276/article/details/104033490

三、二叉树添加节点

完全二叉树添加节点是从上到下、从左到右添加的,普通二叉树添加节点没有规律,节点的添加是按需添加的,二叉树的子节点分为左子节点和右子节点,所以实现两个添加节点的方法,分别添加左子节点和右子节点。

    def add_left_child(self, parent, value):
        """添加左子节点"""
        if parent is None:
            print("父节点不存在")
            return
        if parent.left_child is not None:
            print("父节点已有左子节点")
            return
        node = value if isinstance(value, Node) else Node(value)
        parent.left_child = node
        node.parent = parent

    def add_right_child(self, parent, value):
        """添加右子节点"""
        if parent is None:
            print("父节点不存在")
            return
        if parent.right_child is not None:
            print("父节点已有右子节点")
            return
        node = value if isinstance(value, Node) else Node(value)
        parent.right_child = node
        node.parent = parent

add_left_child(parent, value):添加左子节点。先给定一个父节点,如果父节点已经有了左子节点,则不能添加,如果父节点的左子节点不存在,则将新节点添加到左子节点的位置。将父节点的 left_child 指向新节点,将新节点的 parent 指向父节点。这个方法支持传入一个新节点,也支持传入新节点中保存的数据。

add_right_child(parent, value):添加右子节点。原理同添加左子节点。

if __name__ == '__main__':
    tree = BinaryTree()
    tree.root = 'A'
    node1 = Node('B')
    tree.add_left_child(tree.root, node1)
    node2 = Node('C')
    tree.add_right_child(tree.root, node2)
    node3 = Node('D')
    node4 = Node('E')
    node5 = Node('F')
    tree.add_right_child(node1, node3)
    tree.add_left_child(node2, node4)
    tree.add_right_child(node2, node5)
    tree.add_left_child(node3, 'G')
    tree.add_left_child(node4, 'H')
    tree.add_right_child(node4, 'I')
    tree.add_right_child(node5, 'J')
    tree.show_tree()

运行结果:

--------------------
A
├─R─C
| ├─R─F
| | ├─R─J
| | └─L─
| └─L─E
|   ├─R─I
|   └─L─H
└─L─B
  ├─R─D
  | ├─R─
  | └─L─G
  └─L─
--------------------

添加数据后的二叉树如下图:

四、二叉树的四种遍历方式

实现二叉树的层序遍历、先序遍历、中序遍历和后序遍历。

    def levelorder_traversal(self):
        """层序遍历"""
        if self.is_empty():
            print('空二叉树')
            return
        queue = list()
        queue.insert(0, self.__root)
        while len(queue):
            cur = queue.pop()
            print(cur.data, end=' ')
            if cur.left_child is not None:
                queue.insert(0, cur.left_child)
            if cur.right_child is not None:
                queue.insert(0, cur.right_child)
        print()

    def preorder_traversal(self, node):
        """先序遍历"""
        if node is None:
            return
        print(node.data, end=' ')
        self.preorder_traversal(node.left_child)
        self.preorder_traversal(node.right_child)

    def inorder_traversal(self, node):
        """中序遍历"""
        if node is None:
            return
        self.inorder_traversal(node.left_child)
        print(node.data, end=' ')
        self.inorder_traversal(node.right_child)

    def postorder_traversal(self, node):
        """后序遍历"""
        if node is None:
            return
        self.postorder_traversal(node.left_child)
        self.postorder_traversal(node.right_child)
        print(node.data, end=' ')

levelorder_traversal(): 二叉树的层序遍历。层序遍历是广度优先遍历,按从上到下、从左到右的顺序遍历二叉树。二叉树的层序遍历必须借助队列或栈,在 Python 中可以直接使用 list 来当队列使用。

preorder_traversal(): 二叉树的先序遍历。

inorder_traversal(): 二叉树的中序遍历。

postorder_traversal(): 二叉树的后序遍历。

关于二叉树的三种深度优先遍历方式,这里使用的是递归的方式,代码是很简单的,关键是理解遍历的顺序。

可以参考:https://blog.csdn.net/weixin_43790276/article/details/105473527

    print('层次遍历: ', end='')
    tree.levelorder_traversal()
    print('先序遍历: ', end='')
    tree.preorder_traversal(tree.root)
    print()
    print('中序遍历: ', end='')
    tree.inorder_traversal(tree.root)
    print()
    print('后序遍历: ', end='')
    tree.postorder_traversal(tree.root)
    print()

使用这四种方式遍历上面添加数据后的二叉树,运行结果如下:

层次遍历: A B C D E F G H I J 
先序遍历: A B D G C E H I F J 
中序遍历: B G D A H E I C F J 
后序遍历: G D B H I E J F C A 

五、二叉树的高度、叶节点和节点数

实现返回二叉树高度(深度)的方法,打印所有叶节点的方法,返回二叉树节点数量的方法,返回第 k 层节点数量的方法。

    def height(self, root):
        """二叉树的深度"""
        if root.data is None:
            return 0
        if root.left_child is None and root.right_child is None:
            return 1
        if root.left_child is not None and root.right_child is None:
            return 1 + self.height(root.left_child)
        if root.left_child is None and root.right_child is not None:
            return 1 + self.height(root.right_child)
        if root.left_child is not None and root.right_child is not None:
            return 1 + max(self.height(root.left_child), self.height(root.right_child))

    def leaves(self, root):
        """二叉树的叶节点"""
        if root.data is None:
            return None
        if root.left_child is None and root.right_child is None:
            print(root.data, end=' ')
        if root.left_child is not None:
            self.leaves(root.left_child)
        if root.right_child is not None:
            self.leaves(root.right_child)

    def node_count(self, root):
        """二叉树的节点个数"""
        return self.node_count(root.left_child) + self.node_count(root.right_child) + 1 if root else 0

    def kth_node_count(self, root, k):
        """二叉树第k层的节点个数"""
        if not root or k <= 0:
            return 0
        if k == 1:
            return 1
        return self.kth_node_count(root.left_child, k-1) + self.kth_node_count(root.right_child, k-1)

height(root): 返回二叉树的高度(深度)。如果二叉树是一棵空二叉树,则树的深度为 0。如果二叉树非空,只有根节点时,二叉树的深度为 1,层数每增加一层,二叉树的深度就加一,使用递归的方式一直找到最深一层。不管是左子树更深还是右子树更深,二叉树的深度都取两者中的最大值。

leaves(root): 获取二叉树的所有叶节点。二叉树的叶节点是没有子节点的节点,如果二叉树是一棵空二叉树,则没有叶节点。如果二叉树非空,只有根节点时,根节点本身就是叶节点。如果根节点有子树,使用递归的方式对子树进行判断,依次找到所有的叶节点。

node_count(root): 返回二叉树的节点个数。如果二叉树是一棵空二叉树,则节点个数为 0。如果二叉树非空,只有根节点时,节点个数为 1,再使用递归的方式对二叉树的左子树和右子树进行判断,节点个数为左子树加右子树加根节点的个数。

kth_node_count(root, k): 返回二叉树第 k 层的节点个数。如果二叉树是一棵空二叉树,则节点个数为 0。如果二叉树非空,k 小于等于 0 时,节点个数为 0,k 为 1 时,节点个数为 1,当 k 为其他值时,返回左子树和右子树的第 k-1 层的节点个数之和。这里为什么要减 1 呢?对于整棵二叉树来说,如 k=3 的节点在树的第三层,在左子树和右子树中,这些节点在左子树和右子树的第二层(3-1),以此类推,递归就可以得出第 k 层的节点个数。

    print('二叉树的深度为:', tree.height(tree.root))
    print('二叉树的叶节点有:', end='')
    tree.leaves(tree.root)
    print()
    print('二叉树的节点数为:', tree.node_count(tree.root))
    print('二叉树的第三层节点数为:', tree.kth_node_count(tree.root, 3))

使用这几个方法查看上面添加节点后的二叉树,运行结果如下:

二叉树的深度为: 4
二叉树的叶节点有:G H I J 
二叉树的节点数为: 10
二叉树的第三层节点数为: 3

六、完整代码

# coding=utf-8
class Node(object):
    """节点类"""
    def __init__(self, data, left_child=None, right_child=None):
        self.data = data
        self.parent = None
        self.left_child = left_child
        self.right_child = right_child


class BinaryTree(object):
    """二叉树类"""
    def __init__(self):
        self.__root = None
        self.prefix_branch = '├'
        self.prefix_trunk = '|'
        self.prefix_leaf = '└'
        self.prefix_empty = ''
        self.prefix_left = '─L─'
        self.prefix_right = '─R─'

    def is_empty(self):
        return not self.__root

    @property
    def root(self):
        return self.__root

    @root.setter
    def root(self, data):
        self.__root = Node(data)

    def show_tree(self):
        if self.is_empty():
            print('空二叉树')
            return
        print('-' * 20)
        print(self.__root.data)
        self.__print_tree(self.__root)
        print('-' * 20)

    def add_left_child(self, parent, value):
        """添加左子节点"""
        if parent is None:
            print("父节点不存在")
            return
        if parent.left_child is not None:
            print("父节点已有左子节点")
            return
        node = value if isinstance(value, Node) else Node(value)
        parent.left_child = node
        node.parent = parent

    def add_right_child(self, parent, value):
        """添加右子节点"""
        if parent is None:
            print("父节点不存在")
            return
        if parent.right_child is not None:
            print("父节点已有右子节点")
            return
        node = value if isinstance(value, Node) else Node(value)
        parent.right_child = node
        node.parent = parent

    def levelorder_traversal(self):
        """层序遍历"""
        if self.is_empty():
            print('空二叉树')
            return
        queue = list()
        queue.insert(0, self.__root)
        while len(queue):
            cur = queue.pop()
            print(cur.data, end=' ')
            if cur.left_child is not None:
                queue.insert(0, cur.left_child)
            if cur.right_child is not None:
                queue.insert(0, cur.right_child)
        print()

    def preorder_traversal(self, node):
        """先序遍历"""
        if node is None:
            return
        print(node.data, end=' ')
        self.preorder_traversal(node.left_child)
        self.preorder_traversal(node.right_child)

    def inorder_traversal(self, node):
        """中序遍历"""
        if node is None:
            return
        self.inorder_traversal(node.left_child)
        print(node.data, end=' ')
        self.inorder_traversal(node.right_child)

    def postorder_traversal(self, node):
        """后序遍历"""
        if node is None:
            return
        self.postorder_traversal(node.left_child)
        self.postorder_traversal(node.right_child)
        print(node.data, end=' ')

    def height(self, root):
        """二叉树的深度"""
        if root.data is None:
            return 0
        if root.left_child is None and root.right_child is None:
            return 1
        if root.left_child is not None and root.right_child is None:
            return 1 + self.height(root.left_child)
        if root.left_child is None and root.right_child is not None:
            return 1 + self.height(root.right_child)
        if root.left_child is not None and root.right_child is not None:
            return 1 + max(self.height(root.left_child), self.height(root.right_child))

    def leaves(self, root):
        """二叉树的叶节点"""
        if root.data is None:
            return None
        if root.left_child is None and root.right_child is None:
            print(root.data, end=' ')
        if root.left_child is not None:
            self.leaves(root.left_child)
        if root.right_child is not None:
            self.leaves(root.right_child)

    def node_count(self, root):
        """二叉树的节点个数"""
        return self.node_count(root.left_child) + self.node_count(root.right_child) + 1 if root else 0

    def kth_node_count(self, root, k):
        """二叉树第k层的节点个数"""
        if not root or k <= 0:
            return 0
        if k == 1:
            return 1
        return self.kth_node_count(root.left_child, k-1) + self.kth_node_count(root.right_child, k-1)

    def __print_tree(self, node, prefix=None):
        if prefix is None:
            prefix, prefix_left_child = '', ''
        else:
            prefix = prefix.replace(self.prefix_branch, self.prefix_trunk)
            prefix = prefix.replace(self.prefix_leaf, self.prefix_empty)
            prefix_left_child = prefix.replace(self.prefix_leaf, self.prefix_empty)
        if self.has_child(node):
            if node.right_child is not None:
                print(prefix + self.prefix_branch + self.prefix_right + str(node.right_child.data))
                if self.has_child(node.right_child):
                    self.__print_tree(node.right_child, prefix + self.prefix_branch + ' ')
            else:
                print(prefix + self.prefix_branch + self.prefix_right)
            if node.left_child is not None:
                print(prefix + self.prefix_leaf + self.prefix_left + str(node.left_child.data))
                if self.has_child(node.left_child):
                    prefix_left_child += '  '
                    self.__print_tree(node.left_child, self.prefix_leaf + prefix_left_child)
            else:
                print(prefix + self.prefix_leaf + self.prefix_left)

    def has_child(self, node):
        return node.left_child is not None or node.right_child is not None

    def __str__(self):
        return str(self.__class__)


if __name__ == '__main__':
    tree = BinaryTree()
    tree.root = 'A'
    node1 = Node('B')
    tree.add_left_child(tree.root, node1)
    node2 = Node('C')
    tree.add_right_child(tree.root, node2)
    node3 = Node('D')
    node4 = Node('E')
    node5 = Node('F')
    tree.add_right_child(node1, node3)
    tree.add_left_child(node2, node4)
    tree.add_right_child(node2, node5)
    tree.add_left_child(node3, 'G')
    tree.add_left_child(node4, 'H')
    tree.add_right_child(node4, 'I')
    tree.add_right_child(node5, 'J')
    tree.show_tree()

    print('层次遍历: ', end='')
    tree.levelorder_traversal()
    print('先序遍历: ', end='')
    tree.preorder_traversal(tree.root)
    print()
    print('中序遍历: ', end='')
    tree.inorder_traversal(tree.root)
    print()
    print('后序遍历: ', end='')
    tree.postorder_traversal(tree.root)
    print()

    print('二叉树的深度为:', tree.height(tree.root))
    print('二叉树的叶节点有:', end='')
    tree.leaves(tree.root)
    print()
    print('二叉树的节点数为:', tree.node_count(tree.root))
    print('二叉树的第三层节点数为:', tree.kth_node_count(tree.root, 3))

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python实现普通二叉树 的相关文章

  • 转载:CCNP学习考试心得

    CCNP学习考试心得 当计算机屏幕上显示 Congralation时 我不禁长出一口气 心中想 终于考完了 我所说的终于考完是指 我终于完成了CCNP考试 四个月的学习 对于某些人来说可能太长了 但是要真正掌握ccnp的内容我感觉四个月还只
  • 手把手教你使用python发送邮件

    前言 发送电子邮件是个很常见的开发需求 平时如果有什么重要的信息怕错过 就可以发个邮件到邮箱来提醒自己 使用 Python 脚本发送邮件并不复杂 不过由于各家邮件的发送机制和安全策略不同 常常会因为一些配置问题造成发送失败 今天我们来举例讲
  • 混合模型简介与高斯混合模型

    高斯混合模型 混合模型概述 In statistics a mixture model is a probabilistic model for representing the presence of subpopulations wit
  • C++primer 阅读随记

    目 录 一 C 基础 1 变量和基本类型 2 字符串 向量和数组 3 表达式 4 语句 5 函数 6 类 二 C 标准库 1 IO库 2 顺序容器 3 泛型算法 4 关联容器 5 动态内存 三 类设计者的工具 1 拷贝控制 2 重载运算与类
  • 实施Microsoft Dynamics 365 CE-5. 配置Dynamics 365 CE组织,包括配置不同的Dynamics 365 CE设置。

    本章将帮助您了解Dynamics 365 CE中为个人和管理员提供的Dynamics 365配置选项 您将了解哪些选项可以为单个用户配置 哪些是管理员用户可以完成的配置 您将了解业务管理和服务管理设置下提供的不同配置选项 您还将了解Dyna

随机推荐

  • RobotFramework之高级API

    一 窗口跳转 跳转页面的时候需要获取句柄 Get Window Handles 获取窗口的句柄 Select Window By Handle 切换到新窗口 但是在seleniumLibrary中只有Select window 所以我们进入
  • Top K问题的两种解决思路

    Top K问题在数据分析中非常普遍的一个问题 在面试中也经常被问到 比如 从20亿个数字的文本中 找出最大的前100个 解决Top K问题有两种思路 最直观 小顶堆 大顶堆 gt 最小100个数 较高效 Quick Select算法 Lee
  • 自适应表格中input框输入文字布局被打乱

    我今天在写一个新增用户表单的时候 发现我只要输入文字 input框的高度就会改变 导致布局被打乱 这是正常排列好的样式 这是我输入中文后的样子 后来我发现输入中文后 input的高度被撑开了 我一开始没有给盒子设置固定的高度以及行高 设置完
  • C 语言基础-什么是常量、变量?

    C 语言基础 常量和变量 常量 只读 常量是只读的固定值 在程序运行期间不会改变 不能被程序修改的量 可以是任意类型 定义常量的方式有两种 使用 define 宏定义 使用 const 关键字 常量大体分为 直接常量 字面常量 符号常量 d
  • python练习61:打印出杨辉三角形,包含二维列表的应用

    打印出杨辉三角形 要求打印出10行如下图 yanghui for i in range 10 yanghui append 构造二维列表 for j in range i 1 if j 0 or j i yanghui i append 1
  • CCF-CSP真题-2022-06-1归一化处理讲解

    题目传送门 这是CCF CSP2022 06的第一题 相比较还是比较简单 较难理解的是方差 每个样本值与全体样本值的平均数之差的平方值的平均数方差 数学计算公式是这样的 然而 用代码来写要简洁得多 这里采用暴力的复杂度算法 for int
  • MySQL utf8mb4 字符集,用于存储emoji表情

    最近在做微信相关的项目 其中MySQL 要存储emoji表情 因此发现我们常用的utf8 字符集根本无法存储表情 网上有不少替代方案 本人还是采用了修改MySQL字符集的方案简单快捷 首先将我们数据库默认字符集由utf8 更改为utf8mb
  • Pandas分组与排序

    Grouping and Sorting 分组 agg 排序 经常需要将数据根据某个字段划分为不同的组 group 进行分析 然后对组里的数据进行特定的操作 pandas的 groupby 操作便是实现这一功能 groupby的过程就是将原
  • jquery的两种常用自动加载方法

    一 jquery JavaScript的三种常用自动加载方法 1 function jQuery 2 function 3 window nl ad function 加载的先后顺序 第一步 代码块1加载 是在css html 信息加载完毕
  • Scala环境配置完成,在命令行还是不能运行

    刚开始我以为是版本兼容的问题 所以下载了很多个版本 发现没用 我找了很久都不知道是什么原因 网上也没找到跟我一样的问题 偶然我发现是系统环境变量PATHEXT中缺少东西 在PATHEXT中添加 bat 然后就可以了
  • AIX系统安装

    1 选择安装介质 CD ROM 现有备份的安装系统 网络安装 Token Ring Ethernet FDDI U盘 服务器通电启动系统 在控制台显示器出现keyboard字符时 按对应的按钮 1 进入系统管理服务模式 SMS 2 指定控制
  • C语言中结构体初始化并清零的方法有几种?

    结构体初始化清零方法 在C语言中 结构体初始化并清零的方法有以下几种 手动赋值为0 结构体定义后在函数内手动将每个成员都赋值为0 例如 struct MyStruct int a char b float c struct MyStruct
  • vue页面基本组成

    作为编写过html的人 vue页面的基本组成是什么呢 如何快速入手vue呢 我来讲下自己的思路 简介 vue是一个前端框架 运行它需要下载node js 后台支撑 下载vs code 代码编辑器 来编辑代码 可配合eliment ui 上百
  • nodejs处理图片文件上传

    如果使用express框架的话 其内置模块就可以直接处理文件上传了 而不需要饱含额外的模块 express版本 3 4 4 1 使用bodyParser过滤器 并且指定上传的目录为public upload 注意这里的目录为相对于expre
  • PyQt5学习笔记--GridLayout、FormLayout和StackedLayout布局

    目录 1 GridLayout布局 2 FormLayout布局 3 StackedLayout布局 1 GridLayout布局 import sys from PyQt5 QtWidgets import class MyWindow
  • select、poll、epoll

    因为实际需要所致 我们不得不考虑在现有的开源 商用的应用服务器之外开发一个 有性能要求 有并发要求的服务端应用 从技术要求的角度来分析一下 用Java实现这件事情我们可能关注的知识层面 在整体上 可能需要我们从下面几个层面出发来考虑 1 在
  • windows多个不同java共存

    windows多个不同java共存 如图我电脑存在java1 8和15 使用时 我会存在工具支持的java版本不一样 有的工具要8才能使用有的工具需要11或者15以上java才能正常使用 于是为了方便快捷便写了这个多java版本共存 jav
  • 微服务SpringCloud

    什么是SpringCloud SpringCloud是由Spring提供的一套能够快速搭建微服务架构程序的框架集 SpringCloud本身不是一个框架 而是一系列框架的统称 SpringClound就是为了搭建微服务架构才出现的 有人将S
  • Linux如何查看系统时间

    文章目录 一 使用date命令查看系统时间 二 通过 var log syslog文件查看系统时间 三 通过 proc uptime文件查看系统运行时间 四 通过hwclock命令查看硬件时间 五 通过timedatectl命令设置系统时区
  • Python实现普通二叉树

    Python实现普通二叉树 二叉树是每个节点最多有两个子树的树结构 本文使用Python来实现普通的二叉树 关于二叉树的介绍 可以参考 https blog csdn net weixin 43790276 article details