二叉树遍历方法总结

106 阅读1分钟

二叉树遍历是二叉树相关问题的基础,今天总结一下二叉树所有遍历方法

前序遍历

迭代

思路:前序遍历的迭代需要手动维护一个栈,因为遍历顺序是中左右,每次取栈尾,因此在存入栈时需要先存右节点再存左节点

function preorderTraversal(root) {
  const res = []
  if (!root) return res
  const stack = [root]
  while (stack.length) {
    let node = stack.pop()
    res.push(node.val)
    node.right && stack.push(node.right)
    node.left && stack.push(node.left)
  }
  return res
}

递归

// 前序
function preorderTraversal(root) {
  if (!root) return
  // 操作根节点
  preorderTraversal(root.left)
  preorderTraversal(root.right)
}

中序遍历

迭代

思路:中序遍历和前序遍历不太一样,处理的节点和访问的节点顺序不一样,因此我们不能直接通过操作栈头或栈尾进行处理,我们需要处理完左节点后需要再找到其父节点进行操作,因此我们可以通过指针的方式进行处理

var inorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const stack = []
  let point = root
  while (point || stack.length) {
    if (point) {
      stack.push(point)
      point = point.left
    } else {
      point = stack.pop()
      res.push(point.val)
      point = point.right
    }
  }
  return res
}

递归

var inorderTraversal = function (root) {
  if (!root) return
  inorderTraversal(root.left)
  // 操作根节点
  inorderTraversal(root.right)
}

后序遍历

迭代

思路:后续遍历顺序为左右中,前序处理的顺序为中左右,因此只需要改一下前序的存储顺序就会变为中右左,再将结果倒过来就变成了左右中

var postorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const stack = [root]
  while (stack.length) {
    let node = stack.pop()
    res.push(node.val)
    node.left && stack.push(node.left)
    node.right && stack.push(node.right)
  }
  return res.reverse()
}

递归

var postorderTraversal = function (root) {
  if (!root) return
  postorderTraversal(root.left)
  postorderTraversal(root.right)
  // 操作根节点
}

层序遍历

var levelOrder = function (root) {
  if (!root) return []
  let res = []
  let stack = [root]
  while (stack.length) {
    let size = stack.length
    let arr = []
    for (let i = 0; i < size; i++) {
      let node = stack.shift()
      arr.push(node.val)
      node.left && stack.push(node.left)
      node.right && stack.push(node.right)
    }
    res.push(arr)
  }
  return res
}