基础
二叉搜索树(BST)是一种特殊的二叉树,它满足以下性质:
对于任意节点:
- 左子树中所有节点的值都小于该节点
- 右子树中所有节点的值都大于该节点
- 且左右子树本身也都是二叉搜索树
因此,对BST进行中序遍历可以得到一个有序(升序)序列。
“BST为什么查找效率高?”
因为每次比较可以排除一半的搜索范围,类似二分查找,所以平均时间复杂度是O(logN)。
“BST的时间复杂度一定是O(logN)吗?”
不一定。在理想情况下,二叉搜索树是比较平衡的,此时查找、插入、删除的时间复杂度是O(logN),但如果数据插入顺序是有序的(比如递增或递减),BST会退化成一条链表,此时时间复杂度会变成O(N)。
也正是因为普通BST会在最坏情况下性能不稳定,才引出了平衡二叉树(AVL)和红黑树。
实现
注意删除逻辑(难点):
- 无孩子直接删除
- 单孩子用子节点替代
- 双孩子用右子树最小节点替换并递归删除该节点
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int v) : val(v), left(nullptr), right(nullptr) {}
};
TreeNode* insert(TreeNode* root, int val)
{
//tip:一版BST不允许重复值
//返回值为root
if (root == nullptr)
{
return new TreeNode(val);
}
TreeNode* cur = root;
TreeNode* parent = nullptr;
while (cur != nullptr)
{
parent = cur;
if (val == cur->val) return root; //不允许重复,直接返回
else if (val > cur->val) cur = cur->right;
else cur = cur->left;
}
TreeNode* newnode = new TreeNode(val);
if (val > parent->val) parent->right = newnode;
else parent->left = newnode;
return root;
}
TreeNode* getMin(TreeNode* root)
{
while(root->left != nullptr)
{
root = root->left;
}
return root;
}
TreeNode* deleteNode(TreeNode* root, int val)
{
if (root == nullptr) return nullptr;
if (val < root->val)
{
root->left = deleteNode(root->left, val);
}
else if (val > root->val)
{
root->right = deleteNode(root->right, val);
}
else
{
if (root->left == nullptr && root->right == nullptr)
{
//没孩子
delete root;
return nullptr;
}
else if (root->left == nullptr && root->right != nullptr)
{
//有一个孩子
TreeNode* tmp = root->right;
delete root;
return tmp;
}
else if (root->left != nullptr && root->right == nullptr)
{
TreeNode* tmp = root->left;
delete root;
return tmp;
}
else
{
//有两个孩子
TreeNode* minNode = getMin(root->right);
root->val = minNode->val;
root->right = deleteNode(root->right, minNode->val);
}
}
return root;
}