Morris遍历

Morris遍历

概述

二叉树遍历的深度优先遍历中,分析了如何用递归和非递归方式实现遍历二叉树,但是那些方法都无法做到空间复杂度为 O(1),对于递归方法,遍历时用到了函数栈,而对于非递归方法,则是直接申请了栈,这两种方法的空间复杂度均与树的高度相关,设树的高度为 h,则空间复杂度为 O(h)。事实上对于二叉树的遍历,还有一种空间复杂度为 O(1) 的方法,这就是——Morris遍历!!!

普通的递归和非递归解法在遍历过程中,在处理完某个节点后都是通过栈结构(函数栈或申请的栈)才可以返回上层去,正是二叉树的结构(只有从父节点指向孩子节点的指针,而没有从孩子节点指向父节点的指针)导致了从下层回到上层会如此困难。而Morris遍历的实质就是避免使用栈结构实现从下层返回上层,而是使下层到上层有指针,根据下层到上层的指针实现从下层到上层的移动。那么怎么才能有下层到上层的指针呢?

二叉树上的很多节点都有大量的空闲指针(如叶节点就有两个空闲指针),比如某些节点没有右孩子节点,那么这个节点的 right 指针就指向 null,我们将之称为空闲状态,而Morris遍历就是使用了这些空闲指针。

Morris遍历

先不管先序遍历、中序遍历、后序遍历的相关概念,我们先看一下Morris遍历的过程

设当前节点为 cur,初始 cur = head,则 cur 按照以下规则移动:

  • 1.若 cur == null,则过程停止,否则继续下面的过程;
  • 2.若 cur 无左子树,则令 cur = cur.right
  • 3.若 cur 有左子树,则找到 cur 左子树上最右的节点,记作 mostRight
    • 1) 若 mostRight.right == null,则令 mostRight.right = cur,即让 mostRightright 指针指向当前节点 cur,然后令 cur = cur.left
    • 2) 若 mostRight.right == cur, 则令 mostRight.right = null,即让 mostRightright 指针指向空,然后令 cur = cur.right

假设有如下的二叉树:

在这里插入图片描述

则根据上面的Morris遍历规则,其遍历如下:

(1)初始状态;

(2)cur 来到节点 4cur 此时有左子树,则找到其左子树的最右节点(即节点 3),发现节点 3 的右指针指向 null,那么让其指向 cur,然后 cur = cur.left

(3)cur 来到节点 2cur 此时有左子树,则找到其左子树的最右节点(即节点 1),发现节点 1 的右指针指向 null,那么让其指向 cur,然后 cur = cur.left

(4)cur 来到节点 1cur 此时没有左子树,则令 cur = cur.right

(5)cur 来到节点 2cur 此时有左子树,则找到其左子树的最右节点(即节点 1),发现节点 1 的右指针指向 cur,则令节点 1 的右指针指向 null,然后令 cur = cur.right

(6)cur 来到节点 3cur 此时没有左子树,则令 cur = cur.right

(7)cur 来到节点 4cur 此时有左子树,则找到其左子树的最右节点(即节点 3),发现节点 3 的右指针指向 cur,则令节点 3 的右指针指向 null,然后令 cur = cur.right

(8)cur 来到节点 6cur 此时有左子树,则找到其左子树的最右节点(即节点 5),发现节点 5 的右指针指向 null,那么让其指向 cur,然后 cur = cur.left

(9)cur 来到节点 5cur 此时没有左子树,则令 cur = cur.right

(10)cur 来到节点 6cur 此时有左子树,则找到其左子树的最右节点(即节点 5),发现节点 5 的右指针指向 cur,则令节点 5 的右指针指向 null,然后令 cur = cur.right

(11)cur

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值