返回

LeetCode 173:剖析二叉搜索树的迭代器——JavaScript 详解

前端

二叉搜索树迭代器:全面解析中序遍历

引言

二叉搜索树(BST)是一种特殊的二叉树,具有快速搜索和高效插入的优点。在计算机科学领域,BST 广泛用于各种算法和数据结构中。在本文中,我们将深入探讨二叉搜索树迭代器,它可以按照中序遍历的顺序(从小到大)访问 BST 中的所有节点。

二叉搜索树的性质

BST 的关键特点在于它的二叉结构和独特的性质:

  • 每个节点的值大于其左子树中的所有节点值
  • 每个节点的值小于其右子树中的所有节点值

这些性质确保了 BST 具有按从小到大的顺序组织数据的特性,使搜索和插入操作变得高效。

中序遍历

中序遍历是一种树的遍历方式,按照以下顺序访问节点:

  1. 访问左子树
  2. 访问根节点
  3. 访问右子树

对于 BST 而言,中序遍历将返回按从小到大排列的节点值列表。

二叉搜索树迭代器

二叉搜索树迭代器是一种数据结构,允许我们按照中序遍历的顺序访问 BST 中的节点。与递归算法不同,迭代器使用栈(一种先进后出的数据结构)来模拟遍历过程。

算法

BST 迭代器的算法如下:

  1. 将根节点压入栈中。
  2. 只要栈不为空,执行以下步骤:
    • 从栈中取出顶部的节点并访问其值。
    • 如果节点有左子树,将左子树的根节点压入栈中。
    • 如果节点有右子树,将右子树的根节点压入栈中。

代码示例(JavaScript)

class BSTIterator {
  constructor(root) {
    this.stack = [];
    this.pushAllLeft(root);
  }

  hasNext() {
    return this.stack.length > 0;
  }

  next() {
    if (!this.hasNext()) {
      throw new Error("No more elements in the iterator.");
    }
    const node = this.stack.pop();
    this.pushAllLeft(node.right);
    return node.val;
  }

  pushAllLeft(node) {
    while (node) {
      this.stack.push(node);
      node = node.left;
    }
  }
}

复杂度分析

  • 时间复杂度: O(n),其中 n 为 BST 中的节点数。迭代器需要访问每个节点一次。
  • 空间复杂度: O(n),这是因为栈数据结构最多需要存储 n 个节点。

实例讲解

让我们考虑一个示例 BST:

      5
    /   \
   3     7
  / \   / \
 2   4 6   8

使用 BST 迭代器中序遍历该 BST,我们将得到以下序列:

2
3
4
5
6
7
8

常见问题解答

1. BST 迭代器的优势是什么?

  • 按中序遍历的顺序高效访问 BST 中的节点。
  • 无需递归,避免栈溢出问题。

2. BST 迭代器有哪些实际应用?

  • 排序数据
  • 查找中位数
  • 范围查询

3. BST 迭代器和递归遍历有何不同?

  • 迭代器使用栈模拟遍历,而递归遍历使用函数调用栈。
  • 迭代器避免了栈溢出的风险,而递归遍历可能会在深度嵌套的 BST 中导致栈溢出。

4. BST 迭代器是否适用于非 BST?

  • 否,BST 迭代器依赖于 BST 的特定性质。它无法用于非 BST。

5. 如何优化 BST 迭代器?

  • 可以使用 Morris 遍历算法优化 BST 迭代器,它使用更少的空间复杂度。

结论

二叉搜索树迭代器是一种强大的工具,可以有效地按照中序遍历的顺序访问 BST 中的节点。它具有 O(n) 的时间和空间复杂度,并且比递归遍历更有效率。掌握 BST 迭代器是计算机科学领域的一项基本技能,广泛应用于各种算法和数据结构中。