Python实现二叉树的增加、删除、层次遍历、先序/后序/中序遍历

学过数据结构的同学一定这种数据结构非常熟悉了,树是一种非常高效的非线性存储结构,学好树对理解一些复杂的算法非常有帮助。树有以下内容需要掌握:

  • 树、二叉树
  • 二叉查找树
  • 平衡二叉查找树、红黑树
  • 递归树

作为一名 Python 程序员,如果把基础的数据结构与算法都自己亲自实现一遍,那么你已经比 90% 的 Python 程序员更优秀了。

今天的我们的目标是使用 Python 来实现一棵二叉树。 二叉查找树、平衡二叉查找树、红黑树、递归树后面也会实现,请保持关注。

先来梳理下概念:树,可以很形象的理解,有根,有叶子,对应在数据结构中就是根节点、叶子节点,同一层的叶子叫兄弟节点,邻近不同层的叫父子节点,非常好理解。

二叉树,就是每个节点都至多有二个子节点的树。

满二叉树,就是除了叶子节点外,每个节点都有左右两个子节点,这种二叉树叫做满二叉树。

完全二叉树,就是叶子节点都在最底下两层,最后一层叶子节都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大,这种二叉树叫做完全二叉树。

二叉树即可以使用链式存储,也可以使用数组来存储,而完全二叉树是使用数据存最省内存的一种结构。

接下来我们使用 Python 实现链式存储的二叉树。

思路:
1、先定义一个节点 node 类,存储数据 item 和左右节点指针
2、再实现二叉树 binary_tree 的类,类应至少有以下属性和方法:
属性:有一个根节点(root) , 它是 node 类。

方法:

  • 插入一个元素(逐层向下插入)。
  • 删除一个元素(按照二叉查找树的方式删除,先查找待删除节点的父节点。 如果父节点不为空, 判断 item 的左右子树,如果左子树为空,那么判断 item 是父节点的左孩子,还是右孩子,如果是左孩子,将父节点的左指针指向 item 的右子树,反之将父节点的右指针指向 item 的右子树,如果右子树为空,那么判断 item 是父节点的左孩子,还是右孩子,如果是左孩子,将父节点的左指针指向 item 的左子树,反之将父节点的右指针指向 item 的左子树,如果左右子树均不为空,寻找右子树中的最左叶子节点 x ,将 x 替代要删除的节点。 ,如果父节点为空,说明不存在该元素 ,删除元素,返回 True ,未删除元素, 返回 False。
  • 获取一个元素的父节点。
  • 层序遍历:按层输出二叉树的元素
  • 中序遍历:先左子树,再根节点,最后右子树
  • 前序遍历:先根节点,再左子树,最后右子树
  • 后序遍历:先左子树,再右子树,最后根节点。

按下来就是编程实现了,请动手自己实现一把。

先实现一个 node 类:


class Node(object):
    def __init__(self, item):
        self.item = item
        self.left = None
        self.right = None

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

这里的 __str__ 方法是为了方便打印。在 print 一个 Node 类时会打印 __str__ 的返回值,例如:print(Node(5)) 就会打印出字符串 5 。

实现一个二叉树类:

class Tree(object):
    def __init__(self):
        # 根节点定义为 root 永不删除,做为哨兵使用。
        self.root = Node('root')

    def add(self, item):
        node = Node(item)
        if self.root is None:
            self.root = node
        else:
            q = [self.root]

            while True:
                pop_node = q.pop(0)
                if pop_node.left is None:
                    pop_node.left = node
                    return
                elif pop_node.right is None:
                    pop_node.right = node
                    return
                else:
                    q.append(pop_node.left)
                    q.append(pop_node.right)

    def get_parent(self, item):
        '''
        找到 Item 的父节点
        '''
        if self.root.item == item:
            return None  # 根节点没有父节点
        tmp = [self.root]
        while tmp:
            pop_node = tmp.pop(0)
            if pop_node.left and pop_node.left.item == item:
                return pop_node
            if pop_node.right and pop_node.right.item == item:
                return pop_node
            if pop_node.left is not None:
                tmp.append(pop_node.left)
            if pop_node.right is not None:
                tmp.append(pop_node.right)
        return
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值