资讯专栏INFORMATION COLUMN

二叉搜索树的Morris中序遍历(O(1)空间)思路

Achilles / 899人阅读

摘要:关于二叉树的遍历,使用栈递归或者仿栈循环都是需要的空间,保证了空间为,时间还是比原来多了一遍。思路对每一个节点,优先找到一个节点,这个节点的作用是,当后续节点遍历到这个位置时,可以直接通过这个节点返回它需要返回的位置。

关于二叉树的遍历,使用栈递归或者仿栈循环都是需要O(N)的空间,Morris Traversal保证了空间为O(1),时间还是O(N)(比原来多了一遍)。

这里只介绍inOrder顺序。

思路:

对每一个cur节点,优先找到一个pre节点,这个pre节点的作用是,当后续cur节点遍历 到这个位置时,可以直接通过这个pre节点返回它需要返回的位置。

例如:

        6
       / 
      4   8
    /  
   2    5

上面当cur节点在6的时候,pre节点会在5,因为后面当cur节点遍历到5的时候,可以通过pre节点直接返回6

cur节点再4的时候,pre节点会在2,当后面cur2的时候,可以直接返回4

pre找到了,是通过什么返回呢,因为不能修改二叉树结构,也不能使用堆栈记录。

通过mirror(镜像),也就是说,当找到pre的时候(每个pre的右节点确保为null),在它的右节点创建一个镜像节点,
这个镜像节点直接指向当前的cur节点。

这个操作是不占用空间的,因为只是互相引用。

例如:当上面的cur6pre5,那么设置pre.right=cur,感觉上是这样:

        6
       / 
      4   8
    /  
   2    5
         
          6
         / 
        4   8
        ...

其实并没有多出来那一块,只是5引用到6罢了

         6
       / ↑ 
      4  ↑  8
    /   ↑
  2      5
  

理解了这些,那么后续就简单了,当cur遍历到pre的时候并且打印后,将pre新增的引用删除恢复原来的树便可。

代码:

function morrisTraversal(root){
  let cur=root,pre
  while(cur!=null){
    // 当左为空,直接打印
    if(cur.left==null){
      console.log(cur.val)
      cur=cur.right
    }else{
      // 当左不为空,先去找 pre
      pre=cur.left
      while(pre.right!=null && pre.right!==cur){
        pre=pre.right
      }
      // 建立引用,用于返回
      if(pre.right==null){
        pre.right=cur
        cur=cur.left
      }else{
        // 删除引用
        console.log(cur.val)
        pre.right=null
        cur=cur.right
      }
    }
  }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100846.html

相关文章

  • 树和树的算法

    摘要:树和树的算法一树树的概念树英语是一种抽象数据类型或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。一种时间复杂度额外空间复杂度的二叉树的遍历方式,为二叉树的节点个数。 树和树的算法 一、树 1.1 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个...

    RaoMeng 评论0 收藏0
  • 树和树的算法

    摘要:树和树的算法一树树的概念树英语是一种抽象数据类型或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。一种时间复杂度额外空间复杂度的二叉树的遍历方式,为二叉树的节点个数。 树和树的算法 一、树 1.1 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个...

    PiscesYE 评论0 收藏0
  • 【递归+迭代详解】二叉树的morris遍历、层序遍历、前序遍历中序遍历、后序遍历

    摘要:递归解法由于层次遍历的递归解法不是主流,因此只介绍前三种的递归解法前序遍历递归递归中序遍历递归递归后序遍历递归递归三种递归遍历的总结递归终止的条件为碰到空节点。 目录 分析二叉树的前序,中序,后序的遍历步骤 1.层序遍历 方法一:广度优先搜索  (以下解释来自leetcode官方题解) 方法...

    niceforbear 评论0 收藏0
  • 【LeetCode 二叉树专项】把二叉搜索树转换为累加树(538)

    摘要:解法一中序遍历分析由于给定了二叉搜索树,因此首先考虑中序遍历,使用示例,我们先来分别看一下二叉搜索树和累加树中序遍历的结果二叉搜索树二叉累加树。这里还是使用示例,我们再来观察一下二叉搜索树和累加树中序遍历的结果二叉搜索树二叉累加树。 ...

    xcold 评论0 收藏0
  • JS中的二叉遍历

    摘要:一个二叉树的例子广度优先遍历广度优先遍历是从二叉树的第一层根结点开始,自上至下逐层遍历在同一层中,按照从左到右的顺序对结点逐一访问。有的书里将二叉树的遍历只讲了上面三种递归遍历。 二叉树是由根节点,左子树,右子树组成,左子树和友子树分别是一个二叉树。这篇文章主要在JS中实现二叉树的遍历。 一个二叉树的例子 var tree = { value: 1, left: { ...

    ghnor 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<