浅谈在面试题中用JS对二叉树的遍历

81 阅读3分钟

引入

在面试中,二叉树的遍历是一个常见的题目。通常面试官会要求候选人解释并实现不同类型的遍历算法。这里我们将讨论四种主要的二叉树遍历方法:先序遍历(Pre-order)、中序遍历(In-order)、后序遍历(Post-order)和层序遍历(Level-order)。这些遍历方式的主要区别在于访问节点的顺序。

什么是二叉树?

二叉树是一种每个节点最多有两个子节点的数据结构,通常分为左子节点和右子节点。它由以下基本元素组成:

  • 根节点(Root) :树的最顶端节点。
  • 节点(Node) :树的基本组成部分,包含数据和指向左右子节点的引用。
  • 叶子节点(Leaf Node) :没有子节点的终端节点。

如何生成树呢?

很简单,有树根,有左右孩子就行了。

function preOrder(root) {
    //  退出条件
    // 空树
  if(root==null)
    return 
  // 递归式
  console.log(root.val);
  preOrder(root.left)
  preOrder(root.right)
}
const root={
    val: 'A',
    left:{
        val:'B',
        left:{
            val:'D'
        },
        right:{
            val:'E'
        }
    },
    right:{
        val:'C',
        left:{
            val:'F'
        },
        right:{
            val:'G'
        }
    }
}
preOrder(root)

遍历二叉树

树的概念就是用递归的概念来定义的

  • 它可以没用根节点,作为一个一棵空树
  • 如果不是空树,那么必须由根节点,左子树和右子树组成,左右子节点分别是一棵二叉树。 所以我们使用递归的思想去遍历二叉树,就是最优解。

先序遍历(Pre-order)

退出条件为root===null,递归公式自顶向下,然后访问顺序,先序遍历首先访问根节点,然后递归地进行左子树的先序遍历,最后递归地进行右子树的先序遍历。其访问顺序为:根 -> 左 -> 右。

function preOrder(root) {
  if (root === null) return;
  console.log(root.val); // 访问当前节点
  preOrder(root.left);   // 遍历左子树
  preOrder(root.right);  // 遍历右子树
}

中序遍历(In-order)

中序遍历首先递归地进行左子树的中序遍历,然后访问根节点,最后递归地进行右子树的中序遍历。其访问顺序为:左 -> 根 -> 右。


function inOrder(root) {
  if (root === null) return;
  inOrder(root.left);    // 遍历左子树
  console.log(root.val); // 访问当前节点
  inOrder(root.right);   // 遍历右子树
}

后序遍历(Post-order)

后序遍历首先递归地进行左子树的后序遍历,然后递归地进行右子树的后序遍历,最后访问根节点。其访问顺序为:左 -> 右 -> 根。

function postOrder(root) {
  if (root === null) return;
  postOrder(root.left);  // 遍历左子树
  postOrder(root.right); // 遍历右子树
  console.log(root.val); // 访问当前节点
}

层序遍历(Level-order)

层序遍历也被称为广度优先搜索(BFS),它按照树的层级从上到下逐层访问所有节点。同一层的节点按照从左到右的顺序访问。此遍历不需要使用递归,而是利用队列来实现。

class TreeNode{
    constructor(val){
        this.val=val;
        this.left=null;
        this.right=null;
    }
}
const root=new TreeNode(1)
root.left=new TreeNode(2)
root.right=new TreeNode(3)
root.left.left=new TreeNode(4)
root.left.right=new TreeNode(5)
root.right.left=new TreeNode(6)

function levelOrderTraversal(root) {
  if (root === null) return [];
  const result = [];
  const queue = [root];
  
  while (queue.length > 0) {
    const currentNode = queue.shift();
    result.push(currentNode.val);
    
    if (currentNode.left !== null) queue.push(currentNode.left);
    if (currentNode.right !== null) queue.push(currentNode.right);
  }
  
  return result;
}
console.log(levelOrderTraversal(root))

总结:

当我们拿到题时,应该先把每一步骤想好,特别是用递归思想的题目,首先是退出条件是什么?其次递归公式是什么? 当想清楚这些,那么下笔如有神。