必须满足的条件:左子树中所有节点的值< 根节点的值 < 右子树中所有节点的值
任意节点的左右子树也是搜索二叉树,也要满足上面的条件
二叉搜索树与堆不同,不一定是完全二叉树,采用链式结构
搜索二叉树的中序遍历是升序
1、查找
数据大于根 往右走 小于根往左走
cpp
TreeNode* search(BinarySearchTree* bst,int num)
{
TreeNode* cur = bst->root;
while(cur != NULL)
{
if(cur->data < num)
{ cur = cur -> right; }
else{ cur= cur -> left;}
else break;
}
return cur;
}
2、插入节点
//1、判断树是否为空 为空创建节点 把数据放入
//2、树不为空 首先判断 这个要插入的数据是否重复 重复直接返回,cur指向要插入数据的位置 perv指向要插入数据的父亲节点
//3、找到位置
//4、将父亲的左/右指向插入的数据节点(看num的值大于prev->data还是小于,大于就是right指向node,小于就是left
cpp
void insert(BinarySearchTree* bst, int num)
{
//1、判断树是否为空 为空创建节点 把数据放入
//2、树不为空 首先判断 这个要插入的数据是否重复 cur指向要插入数据的位置 perv指向要插入数据的父亲节点
//3、找到位置
//4、将父亲的左/右指向插入的数据节点
if(bst -> root = NULL)
{
bst->root = newTreeNode(num);//创建新节点 把数据放进去
return;
}
TreeNode* cur = bst->root, *prev = NULL;
while(cur != NULL) //等于NULL不能再进入循环
{
if(cur->data = num)
{ return; }
prev = cur;
if(cur -> data < num)
{ cur = cur -> right; }
else { cur = cur ->left;}
}
TreeNode* node = newTreeNode(num);
if(prev -> data < num)
{ prev ->right = node;}
else { prev -> left = node;}
}
3、删除节点
1、找到要删除的节点
2、看节点的度
节点度为0/1:让要被删除的节点的父亲节点指向要被删除的节点的孩子
节点度为2:找替换节点;找左子树中的最大的或者右子树中的最小的。
查找cur在中序遍历中的下一个节点(即右子树的最小值);将找到的这个节点删除;将删除节点的值赋值给cur的值。
cpp
void removeItem(BinarySearchTree* bst, int num)
{
if(bst -> root == NULL)
{ return;}
TreeNode* cur = bst->root, *prev = NULL;
while(cur != NULL) //cur可以指向空,只是指向空之后就不能再进入循环了
{
if(cur->data = num) break;
prev = cur;
if(cur -> data < num)
{ cur = cur -> right;}
else { cur = cur -> left;}
}
if(cur == NULL) return; //没有找到要删除的值 直接退出
if(cur->left == NULL || cur->right == NULL)
{ TreeNode* child = cur ->left != NULL ? cur->left : cur->right;
if(pre->right == cur){pre ->right = child;}
else{ pre->left =child;}
free(cur);
}
else{
TreeNode* tmp = cur->right;
while(tmp->left !=NULL)
{tmp = tmp -> left;}
int tmpval = tmp->data;
removeItem(bst,tmp->val);//删除找到的右子树的最小值
cur -> data = tmpval;
}
}

cpp
class Solution {
public:
bool isValidBSTHelp(struct TreeNode* root,long min_val, long max_val)
{
if(root == NULL) return true;//空树也是BST
if(root->val <= min_val || root->val >= max_val)
return false; //树根的值必须在这个范围内
//根的值是左子树的上界 是右子树的下界 两个同时满足才可返回true
return isValidBSTHelp(root->left,min_val,root->val)&&
isValidBSTHelp(root->right,root->val,max_val);
}
bool isValidBST(TreeNode* root)
{
return isValidBSTHelp(root,LONG_MIN,LONG_MAX);//两个宏值
}
};

cpp
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
//从根节点开始遍历
//如果插入的值大于根往右走,判断根的右是不是为空
//为空直接建节点就让pos->right = val
//走一步判断右(pos->right)是否为空,为空就pos->right = val
//左边也是同理
struct TreeNode* creatTreeNode(int val) {
struct TreeNode* ret = malloc(sizeof(struct TreeNode));
ret->val = val;
ret->left = ret->right = NULL;
return ret;
}
struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {
if (root == NULL) {
root = creatTreeNode(val);
return root;
}
struct TreeNode* pos = root;//指向根
while (pos != NULL) {
if (val < pos->val) { //往左走
if (pos->left == NULL) { //看左边是不是为空
pos->left = creatTreeNode(val); //为空直接链入左子树
break;
} else {
pos = pos->left; //左不为空继续往左走
}
} else {
if (pos->right == NULL) {
pos->right = creatTreeNode(val);
break;
} else {
pos = pos->right;
}
}
}
return root;
}

cpp
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
TreeNode *cur = root, *curParent = nullptr;
while (cur && cur->val != key) {
curParent = cur;
if (cur->val > key) {
cur = cur->left;
} else {
cur = cur->right;
}
}
if (!cur) {
return root;
}
if (!cur->left && !cur->right) {
cur = nullptr;
} else if (!cur->right) {
cur = cur->left;
} else if (!cur->left) {
cur = cur->right;
} else {
TreeNode *successor = cur->right, *successorParent = cur;
while (successor->left) {
successorParent = successor;
successor = successor->left;
}
if (successorParent->val == cur->val) {
successorParent->right = successor->right;
} else {
successorParent->left = successor->right;
}
successor->right = cur->right;
successor->left = cur->left;
cur = successor;
}
if (!curParent) {
return cur;
} else {
if (curParent->left && curParent->left->val == key) {
curParent->left = cur;
} else {
curParent->right = cur;
}
return root;
}
}
};