关于二叉树常见的四种遍历方式【JS】

50 阅读2分钟

二叉树四种遍历写法小结

[144] 二叉树的前序遍历

递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const traverse = (node) => {
    if (!node) {
      return
    }
    res.push(node.val)
    traverse(node.left)
    traverse(node.right)
  }
  traverse(root)
  return res
}

非递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const stack = [root]
  while (stack.length) {
    const node = stack.pop()
    if (!node) {
      res.push(stack.pop().val)
      continue
    }
    node.right && stack.push(node.right)
    node.left && stack.push(node.left)
    stack.push(node)
    stack.push(null)
  }
  return res
}

[94] 二叉树的中序遍历

递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function (root) {
  const res = []
  const traverse = (node) => {
    if (!node) return
    traverse(node.left)
    res.push(node.val)
    traverse(node.right)
  }
  traverse(root)
  return res
}

非递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const stack = [root]
  while (stack.length) {
    const node = stack.pop()
    if (!node) {
      res.push(stack.pop().val)
      continue
    }
    node.right && stack.push(node.right)
    stack.push(node)
    stack.push(null)
    node.left && stack.push(node.left)
  }
  return res
}

[145] 二叉树的后序遍历

递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function (root) {
  const res = []
  const traverse = (node) => {
    if (!node) return
    traverse(node.left)
    traverse(node.right)
    res.push(node.val)
  }
  traverse(root)
  return res
}

非递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function (root) {
  const res = []
  if (!root) return res
  const stack = [root]
  while (stack.length) {
    const node = stack.pop()
    if (!node) {
      res.push(stack.pop().val)
      continue
    }
    stack.push(node)
    stack.push(null)
    node.right && stack.push(node.right)
    node.left && stack.push(node.left)
  }
  return res
}

层序遍历小结

[102] 二叉树的层序遍历

/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    const tmpArr = []
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      tmpArr.push(node.val)
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
    res.push(tmpArr)
  }
  return res
}

[107] 二叉树的层序遍历 II

/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrderBottom = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    const tmpArr = []
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      tmpArr.push(node.val)
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
    res.unshift(tmpArr)
  }
  return res
}

二叉树的右视图

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var rightSideView = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      i === size - 1 && res.push(node.val)
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
  }
  return res
}

二叉树的层平均值

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var averageOfLevels = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    let sum = 0
    const size = queue.length
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      sum += node.val
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
    res.push(sum / size)
  }
  return res
}

N 叉树的层序遍历

/**
 * // Definition for a _Node.
 * function _Node(val,children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */

/**
 * @param {_Node|null} root
 * @return {number[][]}
 */
var levelOrder = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    const arr = []
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      arr.push(node.val)
      node.children.forEach((childNode) => {
        childNode && queue.push(childNode)
      })
    }
    res.push(arr)
  }
  return res
}

在每个树行中找最大值

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var largestValues = function (root) {
  const res = []
  if (!root) return res
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    let max = -Infinity
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      max = Math.max(max, node.val)
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
    res.push(max)
  }
  return res
}

填充每个节点的下一个右侧节点指针

/**
 * @param {_Node} root
 * @return {_Node}
 */
var connect = function (root) {
  if (!root) return null
  const queue = [root]
  while (queue.length) {
    const size = queue.length
    let pre = null
    for (let i = 0; i < size; i++) {
      const node = queue.shift()
      if (i === 0) {
        pre = node
      } else {
        pre.next = node
        pre = node
      }
      if (i === size - 1) node.next = null
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
  }
  return root
}

填充每个节点的下一个右侧节点指针 II

/**
 * @param {_Node} root
 * @return {_Node}
 */
var connect = function (root) {
  if (!root) return null
  const queue = [root]
  while (queue.length) {
    const len = queue.length
    let pre = null
    for (let i = 0; i < len; i++) {
      const node = queue.shift()
      if (i === 0) {
        pre = node
      } else {
        pre.next = node
        pre = node
      }
      if (i === len - 1) {
        node.next = null
      }
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
  }
  return root
}

二叉树的最大深度

/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function (root) {
  if (!root) return 0
  let res = 0
  const queue = [root]
  while (queue.length) {
    const len = queue.length
    for (let i = 0; i < len; i++) {
      const node = queue.shift()
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
    res++
  }
  return res
}

二叉树的最小深度

/**
 * @param {TreeNode} root
 * @return {number}
 */
var minDepth = function (root) {
  if(!root) return 0
  let res = 0
  const queue = [root]
  while(queue.length) {
    const len = queue.length
    res++
    for(let i = 0; i < len; i++) {
      const node = queue.shift()
      if(!node.left && !node.right) {
        return res
      }
      node.left && queue.push(node.left)
      node.right && queue.push(node.right)
    }
  }
}