10.二叉树遍历

83 阅读1分钟

二叉树遍历无非就是递归迭代

递归有三种方式:先序中序后序,框架如下:

function dfs(root) {
  if (!root) return
  
  // 前序
  dfs(root.left)
  // 中序
  dfs(root.right)
  // 后序
}

迭代有四种方式:先序中序后序层序,框架如下:

// 层序
function bfs(root) {
  let queue = root ? [root] : []
  for (let cur = null, len = queue.length; len; len = queue.length) {
    // 当前层有len个节点
    while(len--){
      cur = queue.shift() // 访问当前层的节点
      // 下层节点即子节点进队列
      cur.left && queue.push(cur.left)
      cur.right && queue.push(cur.right)
    }
  }
}

// 先序迭代
function dfs(root) {
  let stk = root ? [root] : []

  for (let cur = null; stk.length;) {
    cur = stk.pop() // 先序访问当前元素
    // 先压右后压左
    cur.right && stk.push(cur.right)
    cur.left && stk.push(cur.left)
  }
}

// 后序迭代(根右左倒过来就行,故借用先序思路稍微调整一下就可以实现)
function dfs(root) {
  let stk = root ? [root] : []
  let stk2 = []
  for (let cur = null; stk.length;) {
    cur = stk.pop()
    stk2.push(cur) // 先收集起来
    // 先压左后压右
    cur.left && stk.push(cur.left)
    cur.right && stk.push(cur.right)
  }

  for (let cur = null; stk2.length;) cur = stk2.pop() // 后序访问当前元素
}

// 中序迭代
function dfs(root) {
  let stk = []
  let cur = root // 当前节点指针
  while (cur || stk.length) {
    if (cur) { // 往死里左压栈
      stk.push(cur)
      cur = cur.left
    } else {
      cur = stk.pop() // 中序访问当前元素
      cur = cur.right // 右压栈
    }
  }
}