二叉搜索树的操作
定义
- 二叉搜索树(BST)是二叉树的一种特殊表示形式,它满足如下特性:
- 每个节点中的值必须大于(或等于)存储在其左侧子树中的任何值。
- 每个节点中的值必须小于(或等于)存储在其右子树中的任何值。
验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
思路1
//思路1:递归 不仅要保证左子节点小于等于根节点,右子节点大于等于根节点,还要保证整个右子树的元素都应该大于根节点
// 即要保存上下界
bool isValidBST(TreeNode* root) {
return helper(root,__LONG_MAX__,__LONG_MAX__); //设置为null时,当成0,对于0会出错,还有卡边界问题,恶心
}
bool helper(TreeNode* root,long low,long upper){
if(root == nullptr){
return true;}
if(low != __LONG_MAX__ && root->val <= low){
return false;} //比下界还小,不符合二叉搜索树规则
if(upper != __LONG_MAX__ && root->val >= upper){
return false;}
if(!helper(root->left,low,root->val)){
return false;}//判断左子树是否是二叉搜索树,最大界限是根节点
if(!helper(root->right,root->val,upper)){
return false;}
return true;
}
思路2
//思路2:通过中序遍历,比较是从小到大排列的
bool isValidBST(TreeNode* root){
if(root == nullptr){
return true;}
vector<int> temp;
stack<TreeNode*> visit;
long min = -__LONG_MAX__; //真无语,卡边界值
while(root != nullptr || !visit.empty()){
if(root != nullptr){
visit.push(root);
root = root->left;
}
else{
root = visit.top(); //每次弹出的就是最左的值,最小
visit.pop();
if(root->val <= min){
//使用min记录上一个值,可以不用保存中序遍历数组
return false;//比上个小,则不满足二叉搜索树规则
}
min = root->val;
root = root->right;
}
}
return true;
}
二叉搜索树查找
给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。
//思路:比较root节点值和给定查找的val大小,相等返回即可,小于则去右子树查找,大于去左子树找,直到为空说明不存在
TreeNode* searchBST(TreeNode* root, int val) {
if(root == nullptr){
return NULL;}
while(root != nullptr){
if(root->val == val){
return root;
}
else if(root->val < val){
root = root->right;
}
else{
root = root->left;
}
}
return NULL;
}
二叉搜索树插入
给定二叉搜索树(BST)的根节点和要插入树中的值将值插入二叉搜索树。返回插入后二叉搜索树的根节点。保证原始二叉搜索树中不存在新值。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。
//思路:一种使整体操作变化最小的经典方法。思想是为目标节点找出合适的叶节点位置,然后将该节点作为叶节点插入
// 1、根据节点值与目标节点值的关系,搜索左子树或右子树;
// 2、重复步骤 1 直到到达外部节点;
// 3、根据节点的值与目标节点的值的关系,将新节点添加为其左侧或右侧的子节点。
// TreeNode* insertIntoBST(TreeNode* root, int val) {
// TreeNode* cur = root;
// TreeNode* temp;