题目:
给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
![举例](https://img-blog.csdnimg.cn/339ec440282545868f894823dab44944.jpg)
递归法
思路:
先找到一个符合范围内的结点,如果结点值小于low,就递归往右结点查找,反之,则往左结点查找。
随后递归确定左右子树的范围,如果左子树不在范围内,则回到上一段,即:找到一个符合范围内的结点,如果结点值小于low,就递归往右结点查找,反之,则往左结点查找。对右子树的处理与之相同。
struct TreeNode* Trim(struct TreeNode*root,int low,int right){
if(root==NULL)
return NULL;
if(root->val<low)
return Trim(root->right,low,right);
else if(root->val>right)
return Trim(root->left,low,right);
else{
root->left=Trim(root->left,low,right);
root->right=Trim(root->right,low,right);
}
return root;
}
struct TreeNode* trimBST(struct TreeNode* root, int low, int high){
return Trim(root,low,high);
}
迭代法
思路:
第一步与递归相同,先从根节点出发寻找第一个在范围内的结点。
随后将其作为根节点,对左右子树进行遍历
遍历左子树:当其左子树非空时,判断如果左子树的值大于low,就一直往左下遍历。否则,将其左子树的右子树作为左子树,进入新一轮的判断。
遍历右子树的思路与之相似。
struct TreeNode* trimBST(struct TreeNode* root, int low, int high){
while(root!=NULL&&(root->val<low||root->val>high)){
if(root->val<low)
root=root->right;
else
root=root->left;
}
//以上从根节点出发寻找第一个在范围内的结点
if(root==NULL)
return NULL;//如果为空,说明该树的结点都不符合要求
struct TreeNode *left_Node=root;
//对左子树进行遍历的指针,初始化指向根节点
struct TreeNode *right_Node=root;
//对右子树进行遍历的指针,初始化指向根节点
while(left_Node->left!=NULL){
if(left_Node->left->val>=low)
left_Node=left_Node->left;
else
left_Node->left=left_Node->left->right;
}
while(right_Node->right!=NULL){
if(right_Node->right->val<=high)
right_Node=right_Node->right;
else
right_Node->right=right_Node->right->left;
}
return root;
}