Python笔记(九)

1. 树的概念

树是一种非线性结构

1.1 树的相关概念

1.1.1 节点的度

一个节点含有的子节点的个数,称为该节点的度,例如A节点的度为3

1.1.2 树的度

一棵树中,最大的节点的度称为树的度。例如下图中树的度为3

1.1.3 叶节点

度数为零的节点。例如:C E F

1.1.4 节点的层次

从根开始算起,根为第一层,根的子节点为第2层,以此类推。

1.1.5 树的高度/深度

树中节点的最大层次,即最多的层次有几层。例如下图中,树的高度为3

1.2 树的特点

  1. 每个节点有零个或多个子节点
  2. 没有父节点的节点称为根节点
  3. 每一个非根节点,有且只有一个父节点
  4. 除了根节点外,每个子节点可以分为多个不想交的子树。

在这里插入图片描述

2. 二叉树

每个节点最多含有两个子树的树称为二叉树。
二叉树的种类有很多,例如:完全二叉树、非完全二叉树、满二叉树等。

2.1 完全二叉树

对于一棵二叉树,假设其深度为d(d>1),除了第d层外,其它各层的节点数均已达到最大值,且第d层所有节点从左向右依次的紧密排列。
在这里插入图片描述

2.2 非完全二叉树

在这里插入图片描述

2.3 满二叉树

所有叶节点都在最底层的完全二叉树
在这里插入图片描述

2.4 平衡二叉树(AVL树)

当且仅当任何节点的两棵子树的高度差不大于1的二叉树
在这里插入图片描述

2.5 排序二叉树(BST)

排序二叉树有以下要求:

  1. 若左子树不空,则左子树上所有节点的值均小于它的根节点的值
  2. 若右子树不空,则右子树上所有节点的值均大于它的根节点的值
  3. 左右子树也分别为二叉排序树

空树也是排序二叉树。
在这里插入图片描述

3. 二叉树的实现

3.1 二叉树的性质

  1. 在第 i 层上,至多有2^(i-1)个节点(i>0)
  2. 深度为k的二叉树,至多有2^k - 1 个节点
  3. 对于任意一棵二叉树,如果其叶节点数为a,而度数为2的节点总数为b,则a = b +1
  4. 最多有n个节点的完全二叉树的深度必为log2(n+1) 即 log以2为底,n+1 的对数
  5. 对完全二叉树,从上至下,从左至右编号,编号为i的结点,左孩子必为2i,右孩子必为2i+1,父节点必为i/2(i=1时为根节点,除外)

3.2 二叉树的添加节点的实现

实现思路:

  1. 判断是否有根节点,如果没有,则添加根节点
  2. 如果有根节点,则创建一个临时的队列,将根节点入队列,然后将根节点出队列
  3. 判断出队列的节点是否包含左节点,如果包含则将左节点入队列,如果不包含则直接指向待添加的节点
  4. 判断出队列的节点是否包含右节点,如果包含则将对应的节点入队列,不包含则直接指向待添加的节点
    实现思路

例如:添加节点7
首先1进队列,然后1出队列,1有左节点2,2进队列。1有右节点3,3进队列。
2出队列,2有左节点4,4进队列。2有左节点5,5进队列
3出队列,3有左节点6,6进队列,3没有右节点,则3的右节点指向节点7
添加完成
代码实现

class MyBinaryTree(object):
    def __init__(self, tree_node=None):
        self.root = tree_node

    def add_node(self, tree_node):
        # 根节点为空
        if self.root is None:
            self.root = tree_node
            return
        # 根节点不为空
        # 新增一个临时队列
        temp_queue = MyQueue()
        # 将头结点添加到队列
        temp_queue.append_end(self.root)
        while temp_queue.size() > 0:
            # 出队列
            temp_node = temp_queue.del_head()
            if temp_node.lNode is not None:
                temp_queue.append_end(temp_node.lNode)
            else:
                temp_node.lNode = tree_node
                return
            if temp_node.rNode is not None:
                temp_queue.append_end(temp_node.rNode)
            else:
                temp_node.rNode = tree_node
                return

3.2 二叉树的广度优先遍历

从根节点开始,按照层级顺序逐层遍历所有的节点。
如下图:广度优先遍历结果为:0 1 2 3 4 5 6 7 8 9
在这里插入图片描述
代码实现

    def breath_first_search(self):
        """
        广度优先遍历
        :return:None
        """
        # 先判断是否有根节点
        if self.root is None:
            return None
        # 存在根节点
        temp_queue = MyQueue()
        temp_queue.append_end(self.root)
        while temp_queue.size() > 0:
            temp_node = temp_queue.del_head()
            print(f"{temp_node.value}", end=" ")
            if temp_node.lNode is not None:
                temp_queue.append_end(temp_node.lNode)
            if temp_node.rNode is not None:
                temp_queue.append_end(temp_node.rNode)

3.3 二叉树的深度优先遍历

3.1 先序遍历

即按照根节点、左节点、右节点的顺序来遍历。
例如: 0 1 3 7 8 4 9 2 5 6

3.2 中序遍历

即按照左节点、根节点、右节点的顺序来遍历。
例如:7 3 8 1 9 4 0 5 2 6

3.3 后序遍历

即按照左节点、右节点、根节点的顺序来遍历。
例如:7 8 3 9 4 1 5 6 2 0

知道中序遍历和先序遍历(或者是后序遍历) 就可以推出二叉树结构。

3.4 代码实现

    def depth_first_search(self, tree_node, front=False, middle=False, back=False):
        if tree_node is not None:
            if front and not middle and not back:
                # 先序遍历,根左右
                print(tree_node.value, end=" ")
                self.depth_first_search(tree_node.lNode, front=True)
                self.depth_first_search(tree_node.rNode, front=True)
            elif middle and not front and not back:
                # 中序遍历,左根右
                self.depth_first_search(tree_node.lNode, middle=True)
                print(tree_node.value, end=" ")
                self.depth_first_search(tree_node.rNode, middle=True)
            elif back and not middle and not front:
                # 后序遍历,左右根
                self.depth_first_search(tree_node.lNode, back=True)
                self.depth_first_search(tree_node.rNode, back=True)
                print(tree_node.value, end=" ")
  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值