返回

从算法思维到数据结构:探索二叉搜索树的奥秘

前端

二叉搜索树的入门向导

在计算机科学的世界中,二叉搜索树(Binary Search Tree,BST)是一种重要的数据结构,凭借其高效的查找和插入操作,它在各种场景中都发挥着不可或缺的作用。

二叉搜索树以其独特的结构和算法而著称,它的核心思想是将数据元素组织成一个有序的树状结构,从而实现快速查找和检索。树中的每个节点包含一个值和指向左子树和右子树的指针。左子树中的值小于父节点的值,而右子树中的值大于父节点的值。这种结构使二叉搜索树能够在O(log n)的时间内完成查找和插入操作,而对于顺序结构(如链表)来说,这些操作需要O(n)的时间复杂度。

JavaScript 实现二叉搜索树

为了更好地理解二叉搜索树的实现和应用,我们将在JavaScript中构建一个二叉搜索树。在 JavaScript 中,可以使用对象来表示树的节点,每个节点包含一个值和指向左子树和右子树的指针。

class Node {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}

利用这个 Node 类,我们可以构建一个二叉搜索树:

class BinarySearchTree {
  constructor() {
    this.root = null;
  }

  insert(value) {
    // 创建一个新的节点
    const newNode = new Node(value);

    // 如果树为空,则将新节点设置为根节点
    if (this.root === null) {
      this.root = newNode;
      return;
    }

    // 在树中查找插入位置
    let currentNode = this.root;
    while (true) {
      // 如果要插入的值小于当前节点的值,则向左查找
      if (value < currentNode.value) {
        // 如果左子树为空,则将新节点插入左子树
        if (currentNode.left === null) {
          currentNode.left = newNode;
          return;
        } else {
          // 否则,向左继续查找
          currentNode = currentNode.left;
        }
      } else {
        // 如果要插入的值大于或等于当前节点的值,则向右查找
        if (currentNode.right === null) {
          // 如果右子树为空,则将新节点插入右子树
          currentNode.right = newNode;
          return;
        } else {
          // 否则,向右继续查找
          currentNode = currentNode.right;
        }
      }
    }
  }

  search(value) {
    // 从根节点开始查找
    let currentNode = this.root;

    // 循环查找,直到找到目标值或到达叶节点
    while (currentNode !== null) {
      // 如果目标值等于当前节点的值,则返回该节点
      if (value === currentNode.value) {
        return currentNode;
      } else if (value < currentNode.value) {
        // 如果目标值小于当前节点的值,则向左查找
        currentNode = currentNode.left;
      } else {
        // 如果目标值大于当前节点的值,则向右查找
        currentNode = currentNode.right;
      }
    }

    // 如果没有找到目标值,则返回 null
    return null;
  }
}

LeetCode题解:173. 二叉搜索树迭代器

LeetCode 173 题要求实现一个二叉搜索树的迭代器,使其能够按中序遍历的顺序访问树中的所有元素。我们可以利用 JavaScript 的生成器函数来实现这个迭代器。

class BSTIterator {
  constructor(root) {
    // 使用栈来存储待访问的节点
    this.stack = [];
    // 从根节点开始遍历
    this.pushAll(root);
  }

  hasNext() {
    // 判断栈是否为空,如果为空则说明没有更多元素可访问
    return this.stack.length > 0;
  }

  next() {
    // 弹出栈顶元素并返回它的值
    const currentNode = this.stack.pop();

    // 将当前节点的右子树的所有左子树入栈
    this.pushAll(currentNode.right);

    // 返回当前节点的值
    return currentNode.value;
  }

  pushAll(node) {
    // 将节点入栈,直到到达叶节点
    while (node !== null) {
      this.stack.push(node);
      node = node.left;
    }
  }
}

通过这个迭代器,我们可以在 JavaScript 中轻松地遍历二叉搜索树中的所有元素:

const tree = new BinarySearchTree();
tree.insert(10);
tree.insert(5);
tree.insert(15);
tree.insert(2);
tree.insert(7);
tree.insert(12);
tree.insert(20);

const iterator = new BSTIterator(tree.root);

while (iterator.hasNext()) {
  console.log(iterator.next());
}

结语

二叉搜索树在实际应用中有着广泛的应用场景,如数据库索引、文件系统目录、内存缓存等。掌握二叉搜索树的数据结构和算法,对于提高编程能力和解决实际问题都大有裨益。希望这篇文章能帮助您更好地理解二叉搜索树,并在实践中灵活运用。