二叉搜索树(BST)

从一棵随机二叉搜索树开始,逐步插入、查找或删除值,同时展示其数组形式并高亮 C++ 代码。

所有内容均在此浏览器中模拟,不会发送到任何服务器。

无步骤

无步骤

二叉搜索树

数组索引

60[0]45[1]85[2]68[5]21[3]55[4]32[8]

数组形式

索引 i 的子节点位于 2i+1 和 2i+2。

  • 无关
  • 已经过
  • 正在比较
  • 已找到
  • 新增
  • 待删除
  • 后继节点

无步骤

代码

#include <iostream>
using namespace std;
class Node { // 节点保存其值和指向两个子节点的指针
private: // 私有属性:只有方法可以访问
int value;
Node* left;
Node* right;
public:
Node(int v) : value(v), left(nullptr), right(nullptr) {}
int getValue() const { return value; }
Node* getLeft() const { return left; }
Node* getRight() const { return right; }
void setValue(int v) { value = v; }
void setLeft(Node* n) { left = n; }
void setRight(Node* n) { right = n; }
};
Node* insert(Node* root, int v) { // 将 v 插入搜索树并返回根节点
if (root == nullptr) // 空位:新节点放在这里
return new Node(v); // 创建新节点
if (v < root->getValue()) // 较小的值放左边,较大的值放右边
root->setLeft(insert(root->getLeft(), v)); // 进入左子树
else
root->setRight(insert(root->getRight(), v)); // 进入右子树
return root;
}
int main() {
Node* root = buildTree(); // 所示的树,已构建完成
root = insert(root, v); // 首次调用,来自 main
return 0; // 操作结束
}

这个工具从一棵随机的二叉搜索树(BST)开始,让你手动修改它:输入1到99的数值,点击插入、查找或删除。每次操作都会在树上以动画逐步展示,节点按其角色着色:正在比较、已经经过、新增、待删除或后继。下方还会以数组形式显示同一棵树,索引 i 的子节点位于 2i+1 和 2i+2,C++代码会高亮正在运行的行。你可以在3到15个节点之间调整规模,生成另一棵树,并回到任意一步。所有内容都在浏览器中模拟。

使用方法

  1. 用滑块设置树的大小,或点击“生成新树”改变起点。
  2. 输入1到99的数值并点击插入、查找或删除;动画会自动开始。
  3. 用上一步和下一步按钮前进或后退,或点击“播放”并调整速度。
  4. 观察着色的节点、树的数组形式以及高亮的C++代码行。

常见问题

什么是二叉搜索树,它保持什么性质?
这是一种二叉树,每个节点最多有两个子节点,左子树的所有值都小于该节点的值,右子树的所有值都大于它。凭借这一性质,每次比较都可以排除剩余路径的一半。
BST中的插入和查找如何工作,代价是多少?
两者都从根开始,把数值与每个节点比较:较小就向左,较大就向右。查找在找到数值或到达 nullptr 时结束;插入则在那个空位创建新节点。它们的代价与树的高度成正比:平衡时为对数级,退化为链时为线性级。
删除的三种情况是什么,为什么要用中序后继?
如果节点是叶子,直接移除;如果有一个子节点,由该子节点取代它的位置;如果有两个子节点,则把中序后继(右子树中最小的值)的值复制到该节点,再删除后继节点。后继是顺序中的下一个值,放在这个位置不会破坏BST性质,而且它没有左孩子,所以删除它属于简单情况。
树如何存储在数组中,为什么会有空位?
采用堆的布局:根放在索引0,索引 i 的子节点放在 2i+1 和 2i+2。如果节点缺少某个子节点,该位置就保持空缺,树越不平衡,空位就越多,因为索引会随深度增长。

相关工具