遍历二叉树的统一迭代法

二叉树的统一迭代法

普通迭代遍历方式无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况,前中后序的迭代法各有区别,那么如何实现统一的代码写法呢

那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记

如何标记呢? 

就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法

JavaScript代码:

迭代法中序遍历

/**
  * @param {TreeNode} root
  * @return {number[]}
  */
 var inorderTraversal = function(root) {
   // 统一迭代法
   const res = []
   if(!root) return res
   const stack = [root]
   while(stack.length){
     const n = stack.pop()
     if(!n){ // 只有遇到空节点的时候,才将下一个节点放进结果集
       res.push(stack.pop().val)
       continue
     }
 ​
     n.right && stack.push(n.right)  // 右先放入栈后访问
     stack.push(n)
     stack.push(null)  // 节点访问过,但是还没有处理,加入空节点做为标记。
     n.left && stack.push(n.left)  //左后放入栈先访问   实现 左-中-右
   }
   return res
 }

迭代法先序遍历

 /**
  * @param {TreeNode} root
  * @return {number[]}
  */
 var inorderTraversal = function(root) {
   // 统一迭代法
   const res = []
   if(!root) return res
   const stack = [root]
   while(stack.length){
     const n = stack.pop()
     if(!n){ // 只有遇到空节点的时候,才将下一个节点放进结果集
       res.push(stack.pop().val)
       continue
     }
 ​
     stack.push(n)
     stack.push(null)  // 节点访问过,但是还没有处理,加入空节点做为标记。
     n.right && stack.push(n.right)  // 右先放入栈后访问
     n.left && stack.push(n.left)  // 左后放入栈先访问   实现 中-左-右
     
   }
   return res
 }

迭代法后序遍历

/**
  * @param {TreeNode} root
  * @return {number[]}
  */
 var inorderTraversal = function(root) {
   // 统一迭代法
   const res = []
   if(!root) return res
   const stack = [root]
   while(stack.length){
     const n = stack.pop()
     if(!n){ // 只有遇到空节点的时候,才将下一个节点放进结果集
       res.push(stack.pop().val)
       continue
     }
 ​    stack.push(n)
     stack.push(null)  // 节点访问过,但是还没有处理,加入空节点做为标记。
     n.left && stack.push(n.left)  //左先放入栈后访问   
     n.right && stack.push(n.right)  // 右后放入栈先访问  实现 左-右-中
   }
   return res.reverse() // 结果集倒序输出即可
 }

 可以做一做leetcode上三道题目,分别是:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值