模拟二叉树 完成广度优先、深度优先遍历【Python】完整代码

1、概述

        属于树状结构的一种,每个节点最多只能有2个分叉,左边的是左子树,右边的是右子树。

2、存储方法

        顺序存储

        链式存储:1个元素域 + 2个地址域(左子树,右子树)

3、模拟二叉树

        1. 定义 节点类,并初始化节点

        需求:接收输入的元素,设置初始左、右子节点为None

# 1. 定义 节点类
class Node:
    # 初始化节点
    def __init__(self, item):
        self.item = item        # 元素域
        self.lchild = None      # 地址域:左子节点
        self.rchild = None      # 地址域:右子节点

        2. 定义 二叉树类,并初始化二叉树

        需求:2.1 接收二叉树的 根节点,没有默认初始值为None

# 2. 定义 二叉树类
class BinaryTree:
    # 2.1 指定二叉树的 根节点
    def __init__(self, root=None):
        self.root = root

        2.2 在二叉树类中,定义 添加数据 函数

        需求:1. 接收要往二叉树中 添加的数据,首先判断根节点是否为空,若为空,则将输入的

                       元素设置为根节点,并结束程序;

                   2. 不为空,设置一个空列表,用于存储二叉树的所有节点,将 根节点 添加到列表中;

                   3. 设置死循环,从头开始获取 存储在列表中的所有节点,判断当前节点的 左子树 是

                        否为空,若为空则将 新节点添加为当前节点的 左子树,若不为空,则将当前节点

                        的左子树加到 列表中;判断右子树同上

# 2.2 添加元素
    def add(self, item):
        """
        往二叉树中 添加数据
        :param item: 要添加的数据
        :return:
        """
        # 1. 判断 根节点是否为空,若为空,当前元素为根节点,程序结束
        if self.root == None:
            self.root = Node(item)
            return

        # 2. 不为空,用列表 存储 二叉树的所有节点
        queue = []
        queue.append(self.root)

        # 3. 循环获取 二叉树中的 节点
        while True:
            cur_node = queue.pop(0)
        # 4. 判断当前节点的 左子树 是否为空
            if cur_node.lchild == None:
                # 4.1 若为空, 则将: 新节点添加为当前节点的 左子树
                cur_node.lchild = Node(item)
                return
            else:
                # 4.2 如果不为空, 则将: 当前节点的左子树加到 队列中
                queue.append(cur_node.lchild)

            # 5. 判断当前节点的 右子树 是否为空
            if cur_node.rchild == None:
                # 5.1 若为空, 则将: 新节点添加为当前节点的 右子树
                cur_node.rchild = Node(item)
                return
            else:
                # 5.2 如果不为空, 则将: 当前节点的右子树加到 队列中
                queue.append(cur_node.rchild)

        2.3 在二叉树类中,定义 遍历(广度优先) 函数

        需求:从根节点一层一层遍历

# 2.3 遍历,广度优先
    def breadth_travel(self):
        # 1. 判断 根节点是否为空
        if self.root == None:
            return

        # 2. 创建队列 存储 二叉树的元素
        queue = []
        queue.append(self.root)     # 添加根节点到队列中

        # 3. 循环获取元素,只要队列不为空,就一直遍历
        while len(queue) > 0:
            # 3.1 队列有数据,从队头获取元素
            node = queue.pop(0)
            # 3.2 打印当前节点的内容
            print(node.item, end=' ')

            # 3.3 判断当前节点是否有左子树, 有就添加到 队列中
            if node.lchild is not None:
                queue.append(node.lchild)

            # 3.4 判断当前节点是否有右子树, 有就添加到 队列中
            if node.rchild is not None:
                queue.append(node.rchild)

        2.4 定义 遍历(深度优先)函数   =>  前序:根,左,右

        需求:按前序打印

# 2.4 遍历,深度优先 => 前序,即:根,左,右
    def preorder_travel(self, root):
        # 1. 判断 根节点 是否为空
        if root is not None:
            # 2. 有则打印
            print(root.item, end=' ')
            # 3. 再拿左子树
            self.preorder_travel(root.lchild)
            # 4. 最后拿右子树
            self.preorder_travel(root.rchild)

        2.5 定义 遍历(深度优先)函数   =>  中序:左,根,右

        需求:按中序打印

# 2.5 遍历,深度优先 => 中序,即:左,根,右
    def inorder_travel(self, root):    # root表示节点
        # 1. 判断根节点是否不为空, 不为空, 就按照 左, 根, 右 顺序逐个获取.
        if root is not None:
            # 2. 左, 递归获取.
            self.inorder_travel(root.lchild)
            # 3. 根
            print(root.item, end=' ')
            # 4. 右, 递归获取.
            self.inorder_travel(root.rchild)

        2.6 定义 遍历(深度优先)函数   =>  后序:左,右,根

        需求:按后序打印

# 2.6 遍历,深度优先 => 后序,即:左,右,根
    def postorder_travel(self, root):    # root表示节点
        # 1. 判断根节点是否不为空, 不为空, 就按照 左, 右, 根 顺序逐个获取.
        if root is not None:
            # 2. 左, 递归获取.
            self.postorder_travel(root.lchild)
            # 3. 右, 递归获取.
            self.postorder_travel(root.rchild)
            # 4. 根
            print(root.item, end=' ')

        3. 测试代码1

        需求:创建节点 和 二叉树

# 3. 测试代码1,创建节点 和 二叉树
def test1():
    # 3.1 创建节点
    node = Node('小林')
    # 3.2 打印节点
    print(node.item)
    # 3.3 创建二叉树对象
    bt = BinaryTree(node)
    print(bt)           # 二叉树
    print(bt.root)      # 二叉树的根节点
    print(bt.root.item)     # 二叉树的根节点的元素域

        4. 测试代码2

        需求:演示队列,为先进先出

# 4. 测试代码2,演示队列,先进先出
def test2():
    queue = []
    queue.append('A')
    queue.append('B')
    queue.append('C')

    print(queue.pop(0))     # [A,B,C] => A
    print(queue.pop(0))     # [B,C] => B
    print(queue.pop(0))     # [C] => C

        5. 测试代码3

        需求:添加元素到二叉树,广度优先遍历

# 5. 测试代码3,添加元素到二叉树,广度优先遍历
def test3():
    # 5.1 创建二叉树
    bt = BinaryTree()
    # 5.2 添加元素
    bt.add('A')
    bt.add('B')
    bt.add('C')
    bt.add('D')
    bt.add('E')
    bt.add('F')
    # 5.3 广度优先遍历, 查看结果
    bt.breadth_travel()
    print()         # 换行美观

        6. 测试代码4

        需求:添加元素到二叉树,深度优先遍历(前序、中序、后序)

# 6. 测试代码4,添加元素到二叉树,深度优先遍历
def test4():
    # 6.1 创建二叉树
    bt = BinaryTree()
    # 6.2 添加元素
    bt.add('0')
    bt.add('1')
    bt.add('2')
    bt.add('3')
    bt.add('4')
    bt.add('5')
    bt.add('6')
    bt.add('7')
    bt.add('8')
    bt.add('9')

    # 6.3 深度优先, 前序
    print('前序: ', end='')
    bt.preorder_travel(bt.root)
    print()

    # 6.4 深度优先, 中序
    print('中序: ', end='')
    bt.inorder_travel(bt.root)
    print()

    # 6.5 深度优先, 后序
    print('后序: ', end='')
    bt.postorder_travel(bt.root)

        7. 在 main函数中,调用测试函数

# 7. 在 main函数中,完成测试
if __name__ == '__main__':
    test1()
    test2()
    test3()
    test4()

完整代码:

# 1. 定义 节点类
class Node:
    # 初始化节点
    def __init__(self, item):
        self.item = item        # 元素域
        self.lchild = None      # 地址域:左子节点
        self.rchild = None      # 地址域:右子节点

# 2. 定义 二叉树类
class BinaryTree:
    # 2.1 指定二叉树的 根节点
    def __init__(self, root=None):
        self.root = root

    # 2.2 添加元素
    def add(self, item):
        """
        往二叉树中 添加数据
        :param item: 要添加的数据
        :return:
        """
        # 1. 判断 根节点是否为空,若为空,当前元素为根节点,程序结束
        if self.root == None:
            self.root = Node(item)
            return

        # 2. 不为空,用列表 存储 二叉树的所有节点
        queue = []
        queue.append(self.root)

        # 3. 循环获取 二叉树中的 节点
        while True:
            cur_node = queue.pop(0)
        # 4. 判断当前节点的 左子树 是否为空
            if cur_node.lchild == None:
                # 4.1 若为空, 则将: 新节点添加为当前节点的 左子树
                cur_node.lchild = Node(item)
                return
            else:
                # 4.2 如果不为空, 则将: 当前节点的左子树加到 队列中
                queue.append(cur_node.lchild)

            # 5. 判断当前节点的 右子树 是否为空
            if cur_node.rchild == None:
                # 5.1 若为空, 则将: 新节点添加为当前节点的 右子树
                cur_node.rchild = Node(item)
                return
            else:
                # 5.2 如果不为空, 则将: 当前节点的右子树加到 队列中
                queue.append(cur_node.rchild)

    # 2.3 遍历,广度优先
    def breadth_travel(self):
        # 1. 判断 根节点是否为空
        if self.root == None:
            return

        # 2. 创建队列 存储 二叉树的元素
        queue = []
        queue.append(self.root)     # 添加根节点到队列中

        # 3. 循环获取元素,只要队列不为空,就一直遍历
        while len(queue) > 0:
            # 3.1 队列有数据,从队头获取元素
            node = queue.pop(0)
            # 3.2 打印当前节点的内容
            print(node.item, end=' ')

            # 3.3 判断当前节点是否有左子树, 有就添加到 队列中
            if node.lchild is not None:
                queue.append(node.lchild)

            # 3.4 判断当前节点是否有右子树, 有就添加到 队列中
            if node.rchild is not None:
                queue.append(node.rchild)

    # 2.4 遍历,深度优先 => 前序,即:根,左,右
    def preorder_travel(self, root):
        if root is not None:

            print(root.item, end=' ')

            self.preorder_travel(root.lchild)

            self.preorder_travel(root.rchild)

    # 2.5 遍历,深度优先 => 中序,即:左,根,右
    def inorder_travel(self, root):    # root表示节点
        # 1. 判断根节点是否不为空, 不为空, 就按照 左, 根, 右 顺序逐个获取.
        if root is not None:
            # 2. 左, 递归获取.
            self.inorder_travel(root.lchild)
            # 3. 根
            print(root.item, end=' ')
            # 4. 右, 递归获取.
            self.inorder_travel(root.rchild)

    # 2.6 遍历,深度优先 => 后序,即:左,右,根
    def postorder_travel(self, root):    # root表示节点
        # 1. 判断根节点是否不为空, 不为空, 就按照 左, 右, 根 顺序逐个获取.
        if root is not None:
            # 2. 左, 递归获取.
            self.postorder_travel(root.lchild)
            # 3. 右, 递归获取.
            self.postorder_travel(root.rchild)
            # 4. 根
            print(root.item, end=' ')


# 3. 测试代码1,创建节点 和 二叉树
def test1():
    # 3.1 创建节点
    node = Node('小林')
    # 3.2 打印节点
    print(node.item)
    # 3.3 创建二叉树对象
    bt = BinaryTree(node)
    print(bt)           # 二叉树
    print(bt.root)      # 二叉树的根节点
    print(bt.root.item)     # 二叉树的根节点的元素域

# 4. 测试代码2,演示队列,先进先出
def test2():
    queue = []
    queue.append('A')
    queue.append('B')
    queue.append('C')

    print(queue.pop(0))     # [A,B,C] => A
    print(queue.pop(0))     # [B,C] => B
    print(queue.pop(0))     # [C] => C

# 5. 测试代码3,添加元素到二叉树,广度优先遍历
def test3():
    # 5.1 创建二叉树
    bt = BinaryTree()
    # 5.2 添加元素
    bt.add('A')
    bt.add('B')
    bt.add('C')
    bt.add('D')
    bt.add('E')
    bt.add('F')
    # 5.3 广度优先遍历, 查看结果
    bt.breadth_travel()
    print()         # 换行美观

# 6. 测试代码4,添加元素到二叉树,深度优先遍历
def test4():
    # 6.1 创建二叉树
    bt = BinaryTree()
    # 6.2 添加元素
    bt.add('0')
    bt.add('1')
    bt.add('2')
    bt.add('3')
    bt.add('4')
    bt.add('5')
    bt.add('6')
    bt.add('7')
    bt.add('8')
    bt.add('9')

    # 6.3 深度优先, 前序
    print('前序: ', end='')
    bt.preorder_travel(bt.root)
    print()

    # 6.4 深度优先, 中序
    print('中序: ', end='')
    bt.inorder_travel(bt.root)
    print()

    # 6.5 深度优先, 后序
    print('后序: ', end='')
    bt.postorder_travel(bt.root)

# 7. 在 main函数中,完成测试
if __name__ == '__main__':
    test1()
    test2()
    test3()
    test4()

挑战成功,太棒啦~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值