一、深度优先搜索(DFS)
- 前序遍历: 访问节点 -> 访问左子树 -> 访问右子树。
- 中序遍历: 访问左子树 -> 访问节点 -> 访问右子树。
- 后序遍历: 访问左子树 -> 访问右子树 -> 访问节点。
示例代码:
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function dfsPreOrder(node, result = []) {
if (!node) return result;
result.push(node.value); // 访问节点
dfsPreOrder(node.left, result); // 访问左子树
dfsPreOrder(node.right, result); // 访问右子树
return result;
}
// 示例用法
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);
console.log(dfsPreOrder(root)); // 输出: [1, 2, 4, 5, 3]
二、广度优先搜索(BFS)
BFS 使用队列来实现,逐层遍历树。
使用队列逐层访问节点,每次访问一个节点后,将其子节点加入队列。
二叉树的**层序遍历**(也称为广度优先遍历)
理解:使用队列先把头结点塞入,然后每次遍历的时候出队列一个结点,然后入队列其左右结点,依次循环
示例代码(使用队列):
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function levelOrderTraversal(root) {
if (!root) return [];
const result = [];
const queue = [root];
console.log('queue', queue);
while (queue.length > 0) {
const levelSize = queue.length;
const currentLevel = [];
for (let i = 0; i < levelSize; i++) {
const currentNode = queue.shift();
currentLevel.push(currentNode.value);
if (currentNode.left) {
queue.push(currentNode.left);
}
if (currentNode.right) {
queue.push(currentNode.right);
}
}
result.push(currentLevel);
}
return result;
}
// 示例用法
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);
console.log(levelOrderTraversal(root)); // 输出: [[1], [2, 3], [4, 5]]
二叉搜索树(BST)
二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树,它具有以下性质:
- 节点结构:每个节点最多有两个子节点,分别是左子节点和右子节点。
- 节点值的排列:
- 对于每个节点,其左子树上所有节点的值都小于该节点的值。
- 其右子树上所有节点的值都大于该节点的值。
- 递归性质:每个子树也是一棵二叉搜索树。
这种结构使得查找、插入和删除操作在平均情况下具有 O(logn)O(logn) 的时间复杂度。不过,在最坏情况下(例如树退化成链表),时间复杂度可能会降到 O(n)O(n)。
- 查找:从根节点开始,依次比较节点值,向左或向右子树递归查找。
- 插入:从根节点开始,找到适合的空位置插入新节点,保持二叉搜索树的性质。
- 删除:删除节点后,需要调整树结构以保持二叉搜索树的性质。
二叉搜索树广泛应用于数据库、搜索算法和许多其他计算机科学领域。
注:二叉搜索树的中序遍历能够保证结点的值从小到大排序。