Tree02-TraversalTree-Non-RecursiveMethod2-DFS

一、设计思路:

在设计脚本时,以中序遍历-非递归为例:
当节点列表中的最后一个元素是一个叶子节点,则把该叶子节点从列表中取出来并且添加到结果列表中,然后取出节点列表中的最后一个元素作为子树来进行判定,如果不是叶子节点,则将该子树取出来,再进行右子树-根节点-左子树的方式分解以后,添加到节点列表中。

二、解决问题:

下面的代码是非递归的方式实现的。
在前期设计代码是遇见了一个很严重的问题,即从列表中取出来的节点是一个叶子节点,对其进行判定是有难度的这期间也尝试了几种解法,都需要对上述的问题进行了特殊化处理,这显然是不具有普遍性的,应该摒弃,而找新的方法。
对于每一次遍历而言,加入节点队列中的元素是右子树、左子树、根节点。在这里的根节点(当前根节点)是一个数值,将其转化为一个树节点的形式,即单个元素生成了一棵单节点的树,如此一来,在节点列表中的元素均是树或者树节点的形式。至此,非递归遍历的3种形式统一为一种形式的遍历结构。

三、算法思想

  1. 使用栈来存放节点
  2. 节点入栈顺序:
    (1) 前序遍历:右子树->左子树->根节点
    (2) 中序遍历:右子树->根节点->左子树
    (3) 后序遍历:根节点->右子树->左子树
  3. 节点出栈顺序:
    s1:若当前栈顶元素是单节点,则将该节点弹出栈
    s2:若当前栈顶元素是子树,则将该子树弹出栈,分解子树,并按照入栈顺序
    s3:重复s1、s2步骤,直到节点栈为空栈

四、代码模块

1. 创建二叉树


# 设计方法-节点链表法

class TreeNode:
    """
    定义树节点
    # 参数说明:
        data : 存储节点数据
        left : 节点左子树
        right: 节点右子树
    """
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


class BinaryTree:
    """创建二叉树"""
    def __init__(self):
        self.root = None  # 初始化根节点
        self.ls = []  # 存储根节点(双亲节点)的位置值的队列

    def insertnode(self, data):

        node = TreeNode(data)  # 实例化树节点
        if self.root is None:
            # 判定树的根节点为空,添加根节点,并将根节点的地址添加到列表中
            self.root = node
            self.ls.append(self.root)
        else:
            rootnode = self.ls[0]  # 取出第一个节点作为当前的根节点(不一定是整个树的根节点,而是双亲节点)
            if rootnode.left is None:  # 当前根节点的左子树是空树
                rootnode.left = node  # 将节点值赋给当前根节点的左子树(此处的node已经是实例化的节点)
                self.ls.append(rootnode.left)  # 将节点值存放在列表中作为双亲节点下次被取出来
            elif rootnode.right is None:  # 当前根节点的右子树是空树
                rootnode.right = node
                self.ls.append(rootnode.right)
                self.ls.pop(0)  # 将列表中的第一个元素弹出,表示已经完成了左右子树的添加

2-前序遍历(非递归方法)

# 非递归遍历-前序遍历
    def preordertraversalnon(self):
        result = []  # 存放中序遍历结果
        treenodes = [self.root]  # 存放顺序-右子树-根节点-左子树

        if self.root is None:
            return

        while treenodes:
            subtree = treenodes.pop()  # 引用类生成的树
            if subtree.right is None and subtree.left is None:
                result.append(subtree.data)
            else:
                if subtree is not None:
                    if subtree.right is not None:
                        treenodes.append(subtree.right)  # 添加当前树的右节点
                    if subtree.left is not None:
                        treenodes.append(subtree.left)  # 添加当前树的左节点
                    if subtree.data is not None:
                        rootnode = TreeNode(subtree.data)  # keypoint: 将当前根节点单独生成一棵单节点树
                        treenodes.append(rootnode)  # 添加当前树的根节点

        return result

3-中序遍历(非递归方法)

# 非递归遍历-中序遍历
    def inordertraversalnon(self):
        result = []  # 存放中序遍历结果
        treenodes = [self.root]  # 存放顺序-右子树-根节点-左子树

        if self.root is None:
            return
        
        while treenodes:
            subtree = treenodes.pop()  # 引用类生成的树
            if subtree.right is None and subtree.left is None:
                result.append(subtree.data)
            else:
                if subtree is not None:
                    if subtree.right is not None:
                        treenodes.append(subtree.right)  # 添加当前树的右节点
                    if subtree.data is not None:
                        rootnode = TreeNode(subtree.data)  # keypoint: 将当前根节点单独生成一棵单节点树
                        treenodes.append(rootnode)  # 添加当前树的根节点
                    if subtree.left is not None:
                        treenodes.append(subtree.left)  # 添加当前树的左节点
                
        return result

4-后序遍历(非递归方法)

 # 非递归遍历-后序遍历
    def postordertraversalnon(self):
        result = []  # 存放中序遍历结果
        treenodes = [self.root]  # 存放顺序-右子树-根节点-左子树
    
        if self.root is None:
            return
    
        while treenodes:
            subtree = treenodes.pop()  # 引用类生成的树
            if subtree.right is None and subtree.left is None:
                result.append(subtree.data)
            else:
                if subtree is not None:
                    if subtree.data is not None:
                        rootnode = TreeNode(subtree.data)  # keypoint: 将当前根节点单独生成一棵单节点树
                        treenodes.append(rootnode)  # 添加当前树的根节点
                    if subtree.right is not None:
                        treenodes.append(subtree.right)  # 添加当前树的右节点
                    if subtree.left is not None:
                        treenodes.append(subtree.left)  # 添加当前树的左节点
    
        return result

5-主函数(非递归方法)

# 主函数
if __name__ == '__main__':
    # 1: 构建树的节点(节点的数据域,节点的左子树,节点的右子树)
    btree = BinaryTree()
    for i in range(0, 10):
        btree.insertnode(i)

    # 2:调用遍历方法

    print('>> 前序遍历-非递归方法:')
    print(btree.preordertraversalnon())
    print('>> 中序遍历-非递归方法:')
    print(btree.inordertraversalnon())
    print('>> 后序遍历-非递归方法:')
    print(btree.postordertraversalnon())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值