二叉搜索树的修改与构造
二叉搜索树的最近公共祖先
- 力扣题目链接
- 顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
- 直接迭代法!
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p,
TreeNode* q) {
while(root)
if(root->val>p->val && root->val>q->val)
root=root->left;
else if(root->val<p->val && root->val<q->val)
root=root->right;
else return root;
return nullptr;
}
二叉搜索树中的插入操作
- 力扣题目链接
- 递归:构造二叉树,前序遍历
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==nullptr){
TreeNode* node=new TreeNode(val);
return node;
}
if(root->val>val)
root->left=insertIntoBST(root->left, val);
else root->right=insertIntoBST(root->right, val);
return root;
}
删除二叉搜索树中的节点
- 力扣题目链接
- 前序,想清楚删除非叶子节点的情况
TreeNode* deleteNode(TreeNode* root, int key) {
// 第一种情况:没找到删除的节点,遍历到空节点直接返回了
if(root==nullptr) return root;
else if(root->val==key){
// 第二种情况:左右孩子都为空(叶子节点),直接删除节点
if(!root->left && !root->right) {
delete root; return nullptr;
}
TreeNode* retNode;
if(!root->left) retNode=root->right;
else if(!root->right) retNode=root->left;
else{
auto cur=root->right;
// 找右子树最左面的节点
while(cur->left!=nullptr) cur=cur->left;
cur->left=root->left;
retNode=root->right;
}
delete root;
return retNode;
}
else if(root->val>key)
root->left=deleteNode(root->left, key);
else root->right=deleteNode(root->right, key);
return root;
}
修剪二叉搜索树
- 力扣题目链接
- 前序,通过递归函数返回值删除节点
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(root==nullptr) return root;
if(root->val<low)
return trimBST(root->right, low, high);
else if(root->val>high)
return trimBST(root->left, low, high);
root->left=trimBST(root->left, low, high);
root->right=trimBST(root->right, low, high);
return root;
}
将有序数组转换为二叉搜索树
- 力扣题目链接
- 巩固循环不变量写法!
TreeNode* traversal(vector<int>& nums, int left, int right){
if(left>right) return nullptr;
// 如果数组长度为偶数,中间位置有两个元素,取靠左边的
int mid=left+(right-left)/2;
TreeNode* root=new TreeNode(nums[mid]);
root->left=traversal(nums, left, mid-1);
root->right=traversal(nums, mid+1, right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
if(nums.empty()) return nullptr;
TreeNode* root=traversal(nums, 0, nums.size()-1);
return root;
}
把二叉搜索树转换为累加树
- 力扣题目链接
- 递归:中序,双指针操作累加,注意是反中序遍历!
int pre=0; // 记录前一个节点的数值
void traversal(TreeNode* root){ // 右中左遍历
if(root==nullptr) return;
traversal(root->right);
root->val+=pre;
pre=root->val;
traversal(root->left);
}
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
二叉树总结
- 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。
参考资料
[1] 代码随想录
[2] Leetcode题解