算法_二叉树_二叉树的迭代遍历

二叉树的迭代遍历

1.栈与递归

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

2.二叉树的前序遍历(迭代法)

二叉树的前序遍历的进栈动画:
在这里插入图片描述
总的来说分为三步:

1. 首先根节点入栈,然后出栈
2. 然后加入根节点的右孩子
3. 然后加入根节点的左孩子,然后出栈

为什么要先进右孩子,后进左孩子呢?因为只有这样出栈的时候才是根节点->左孩子->右孩子,符合前序遍历的要求。

代码如下:

def preordertraversal(root):
    result = [] # 存放结果,存放节点数值
    stack = [] # 栈,存放节点指针
    # 如果树为空树,则直接返回空
    if root == None:
        return result
    # 如果树不为空
    # 先对栈进行初始化,将root压入栈中
    stack.append(root)

    # 判断当栈不为空时
    while stack:
        # 栈顶元素出栈
        node = stack.pop()
        result.append(node.value)

        # 栈顶元素的右孩子进栈
        if node.right != None:
            stack.append(node.right)
        # 栈顶元素的左孩子进栈
        if node.left != None:
            stack.append(node.left)
    
    return result

3.二叉树的中序遍历(迭代法)

在这里插入图片描述
总体步骤如下:

  1. 先使用一个指针一直向左遍历,然后将遍历到的节点存入栈中。
  2. 将栈顶元素出栈,将栈顶元素的数值存入result中,然后将指针指向该栈顶元素的右孩子。
  3. 重复第2步,直到指针指向空或者栈为空。

代码如下:

def inordertraversal(root):
    result = [] # 存放结果,存放节点数值
    stack = [] # 栈,存放节点指针
    # 如果树为空树,则直接返回空
    if root == None:
        return result
    # 如果树不为空
    # 先对指针进行初始化
    cur = root
    
    # 判断当栈不为空时
    while cur != None or stack:
        # 一直向左遍历
        if cur != None:
        	stack.append(cur)
        	cur = cur.left # 获取左孩子
		else:
			# 栈顶元素出栈
			cur = stack.pop()
			result.append(cur.value)
			# 获取栈顶元素的右孩子
			cur = cur.right
    
    return result

4.二叉树的后序遍历(迭代法)

直接使用栈来迭代二叉树的后序遍历实现难度很大,我们可以换一个思路;因为前序遍历很容易写并且容易理解,所以我们从前序遍历入手,调整一下前序遍历的入栈顺序,先让前序遍历根节点入栈,然后左孩子入栈,然后右孩子入栈,这样获得的结果就是中右左,然后我们再将result逆序即可。
在这里插入图片描述
代码如下:

def postordertraversal(root):
    result = [] # 存放结果,存放节点数值
    stack = [] # 栈,存放节点指针
    # 如果树为空树,则直接返回空
    if root == None:
        return result
    # 如果树不为空
    # 先对栈进行初始化,将root压入栈中
    stack.append(root)

    # 判断当栈不为空时
    while stack:
        # 栈顶元素出栈
        node = stack.pop()
        result.append(node.value)

		# 栈顶元素的左孩子进栈
        if node.left != None:
            stack.append(node.left)
        # 栈顶元素的右孩子进栈
        if node.right != None:
            stack.append(node.right)
        
    return result[::-1]

5.总结

算法

  1. 先序遍历注意点:

    (1)初始化stack,将root传入stack中
    (2)然后stack栈顶元素出栈,把结果放入result中,然后右孩子入栈,再左孩子入栈即可。
    (3)循环判断条件为stack不为空

  2. 中序遍历注意点:
    (1)初始化一个指针,用来遍历当前的节点
    (2)首先需要让指针一直向左直到指向节点没有左孩子。
    (3)然后弹出栈顶元素,将栈顶元素的数值传入result
    (4)然后让指针指向栈顶元素的右孩子
    (5)循环判断条件为指针不为空或者栈不为空

  3. 后序遍历注意点:

    (1)将前序遍历的入栈顺序改为中右左
    (2)然后再逆序result数组就变味了左右中,即为后序遍历的顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值