二叉树的遍历是指按照某种顺序访问二叉树中的所有节点。遍历方式主要分为两大类:深度优先搜索(DFS)和广度优先搜索(BFS)。其中,深度优先搜索又细分为三种常见的遍历方式,而广度优先搜索通常指的是按层次遍历。
深度优先搜索(DFS)
在深度优先搜索中,遍历会尽可能深入子树,直到达到叶子节点后才会回溯到上一个节点并继续访问其他未访问过的分支。DFS有以下三种遍历方式:
-
前序遍历(Pre-order Traversal):
- 访问根节点。
- 递归地进行左子树的前序遍历。
- 递归地进行右子树的前序遍历。
前序遍历的结果是首先输出根节点的值,然后依次输出左子树和右子树的所有节点。
-
中序遍历(In-order Traversal):
- 递归地中序遍历左子树。
- 访问根节点。
- 递归地中序遍历右子树。
对于二叉搜索树来说,中序遍历将产生一个升序排列的节点值序列。
-
后序遍历(Post-order Traversal):
- 递归地进行左子树的后序遍历。
- 递归地进行右子树的后序遍历。
- 访问根节点。
后序遍历适用于需要先处理子节点再处理父节点的情况,例如删除二叉树时,确保子节点先被删除。
广度优先搜索(BFS)
广度优先搜索,也称为按层次遍历(Level-order Traversal),是从根节点开始逐层访问节点,同一层的节点从左至右访问。当一层的节点全部访问完毕后,接着访问下一层的节点,以此类推直到所有的节点都被访问过。
- 使用队列来辅助实现,将根节点入队,然后重复以下步骤直到队列为空:
- 出队队首元素,并访问该节点。
- 将该节点的左子节点(如果存在)入队。
- 将该节点的右子节点(如果存在)入队。
实现示例
以下是用JavaScript实现上述四种遍历方式的例子:
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function preOrderTraversal(node) {
if (node !== null) {
console.log(node.value);
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
}
function inOrderTraversal(node) {
if (node !== null) {
inOrderTraversal(node.left);
console.log(node.value);
inOrderTraversal(node.right);
}
}
function postOrderTraversal(node) {
if (node !== null) {
postOrderTraversal(node.left);
postOrderTraversal(node.right);
console.log(node.value);
}
}
function levelOrderTraversal(root) {
if (root === null) return;
let queue = [root];
while (queue.length > 0) {
let currentNode = queue.shift();
console.log(currentNode.value);
if (currentNode.left !== null) queue.push(currentNode.left);
if (currentNode.right !== null) queue.push(currentNode.right);
}
}
这些函数可以用于遍历任意二叉树结构,并根据具体的需求打印或处理每个节点的数据。