目录
1.二叉搜索书的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/submissions/
class Solution {
public:
//有序的二叉树,要判断大小减少遍历的时间
//前序遍历 中左右
//核心规律:rootd节点是数值在[p, q]区间中则说明该节点cur就是最近公共祖先
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//1.终止条件
if(root == NULL) return root;
if(p->val < root->val && q->val < root->val ) {
TreeNode* leftnode = lowestCommonAncestor(root->left,p,q);
if(leftnode) return leftnode;
}else if(p->val > root->val && q->val > root->val){
TreeNode* rightnode = lowestCommonAncestor(root->right,p,q);
if(rightnode) return rightnode;
}
//root->val 在两者之间 为两者的公共祖先
return root;
}
};
2.二叉搜索树的插入操作
https://leetcode.cn/problems/insert-into-a-binary-search-tree/submissions/
class Solution {
public:
//中左右 前序遍历
//根据大小判断往那个方向遍历
TreeNode* insertIntoBST(TreeNode* root, int val) {
//终止条件
if(root == nullptr) {
TreeNode* node = new TreeNode(val);
return node;
}
if(val < root->val){
root->left = insertIntoBST(root->left,val);
}
if(val > root->val){
root->right = insertIntoBST(root->right,val);
}
return root;
}
};
3.删除二叉搜索书的节点
https://leetcode.cn/problems/delete-node-in-a-bst/submissions/
class Solution {
public:
//中左右 中序遍历
TreeNode* deleteNode(TreeNode* root, int key) {
//1.终止条件
if(root == nullptr) return root;
if(key == root->val){
if(root->left == nullptr){ //左子树为空
return root->right;
}else if(root->right == nullptr){ //右子树为空
return root->left;
}else{ //左右子树都不为空
TreeNode* cur = root->right; // 找右子树最左面的节点
while(cur->left != nullptr) {
cur = cur->left;
}
cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置
TreeNode* tmp = root; // 把root节点保存一下,下面来删除
root = root->right; // 返回旧root的右孩子作为新root
delete tmp; // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)
return root;
}
}
if(key < root->val){
root->left = deleteNode(root->left,key);
}
if(key > root->val){
root->right = deleteNode(root->right,key);
}
return root;
}
};
4.修建二叉搜索树
https://leetcode.cn/problems/trim-a-binary-search-tree/
class Solution {
public:
//要将小于low的节点全部删除 也就是若low节点存在,则将其左子树删除
//若low不存在,则要将小于low的节点删除
//要将大于high的节点全部删除,也就是high的节点的右子树全部删除
//若high节点不存在,那么则删除
//判断当前节点与low high的关系确定遍历方向
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(root == nullptr) return nullptr;
//如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
if(root->val > high){
TreeNode* leftnode = trimBST(root->left,low,high);
return leftnode;
}
//如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。
if(root->val < low){
TreeNode* rightnode = trimBST(root->right,low,high);
return rightnode;
}
//接下来要将下一层处理完左子树的结果赋给root->left,处理完右子树的结果赋给root->right。
root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子
root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
return root;
}
};
5.将有序数组转化为二叉搜索树
https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/
class Solution {
public:
//本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间
//如果数组长度为偶数,中间节点有两个,取哪一个?取哪一个都可以,只不过构成了不同的平衡二叉搜索树。
//中序遍历 钟左右
TreeNode* traversal(vector<int>& nums,int left,int right){
//终止
if(left > right) return nullptr; //左闭右闭
//构造根节点
int i = left + ((right - left) / 2);
TreeNode* root = new TreeNode(nums[i]);
root->left = traversal(nums,left,i-1); //左闭右闭
root->right = traversal(nums,i+1,right); //左闭右闭
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode*root = traversal(nums,0,nums.size()-1);
return root;
}
};
6.把二叉树转化为累加树
https://leetcode.cn/problems/convert-bst-to-greater-tree/
class Solution {
public:
//将节点的值修改为>=节点值的和
//相当于从后往前遍历
//二叉搜索树的顺序时左中右,现在到这遍历相当于 右中左
TreeNode* pre;
TreeNode* convertBST(TreeNode* root) {
if(root == nullptr) return root;
root->right = convertBST(root->right);
if(pre != nullptr){
root->val += pre->val;
}
pre = root;
root->left = convertBST(root->left);
return root;
}
};
class Solution {
public:
//将节点的值修改为>=节点值的和
//相当于从后往前遍历
//二叉搜索树的顺序时左中右,现在到这遍历相当于 右中左
int pre;
void traversal(TreeNode* root){
if(root == nullptr) return ;
traversal(root->right);
root->val += pre;
pre = root->val;
traversal(root->left);
return;
}
TreeNode* convertBST(TreeNode* root) {
pre = 0;
traversal(root);
return root;
}
};