一、前言
参考文献:代码随想录
今天的题目主要是对二叉搜索树的修剪和创建以及转化的操作,使其对二叉搜索树更加的了解,操作更加熟悉。
二、修剪二叉搜索树
2、思路:
修剪二叉树不需要删除节点,但是需要改变结点的指向,思路我总结了以下几点:
(1)利用递归来修剪二叉树,返回值,参数如下:
TreeNode* trimBST(TreeNode* root, int low, int high)
low 和 high是用来划分范围的。
(2)通过前序遍历,来找符合的区间,而不是只是调用一次trimBST,需要return此函数,才能一直往下找,才能找到符合的位置。
if (root->val < low) {
return trimBST(root->right, low, high);
}
if (root->val > high) {
return trimBST(root->left, low, high);
}
(3)当然在写单层遍历之前,别忘了设置终止条件
if (root == NULL) return NULL;
(4)中:只需要接住返回来的节点即可:
root->left = trimBST(root->left, low, high); // node->left去接住修剪后的子树
root->right = trimBST(root->right, low, high);// 同理
2、整体代码如下:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == NULL) return NULL;
if (root->val < low) {
// auto temp = root->right;
// delete root;
// 一直往下修剪
return trimBST(root->right, low, high);
}
if (root->val > high) {
// 不可以直接删除,会导致内存的溢出
// auto temp = root->left;
// delete root;
// 一直往下修剪
return trimBST(root->left, low, high);
}
root->left = trimBST(root->left, low, high); // node->left去接住修剪后的子树
root->right = trimBST(root->right, low, high);// 同理
return root;
}
};
三、将有序数组转化为有序二叉树
1、思路:
我的第一思路就是先把数组从小到大排个序,但是这样并不能准确找到节点,所以只能放弃了;
正确思路如下:
(1)使用递归来解决这个问题,返回值和参数如下:
TreeNode* makeTree(vector<int>& nums, int left, int right)
左右指针,是来划分子树在nums中的范围的,TreeNode的返回值,是为了连接各个节点;
(2)首先还是终止条件,终止条件就比较不一般了,如果left大于right就代表可以中止了:
if (left > right) return NULL;
(3)采用的是前序遍历,先设立节点,然后用左右递归,去记住子节点:
int mid = (left + right) / 2; // 进位运算
// 创建新节点
TreeNode* root = new TreeNode(nums[mid]);
// 左右递归,创建
root->left = makeTree(nums, left, mid - 1);
root->right = makeTree(nums, mid + 1, right);
2、整体代码如下:
class Solution {
private:
// 设置左右边界来确定根节点的位置,并且一直采用左闭右闭的区间
TreeNode* makeTree(vector<int>& nums, int left, int right) {
if (left > right) return NULL;
// 确定结点的位置
int mid = (left + right) / 2; // 进位运算
// 创建新节点
TreeNode* root = new TreeNode(nums[mid]);
// 左右递归,创建
root->left = makeTree(nums, left, mid - 1);
root->right = makeTree(nums, mid + 1, right);
return root;
}
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return makeTree(nums, 0 ,nums.size() - 1);
}
};
四、把二叉搜索树转化为累加树
1、思路:
还是使用递归,这里需要用到双指针,类似于前两天的最小绝对差和众数的题目,如果不用双指针,就统计不到前一个指针的数值了。
(1)返回值和参数如下:
void sumBST(TreeNode* root)
为什么为空呢?因为传入的是root的地址。。而且要求返回的也是root,并且有双指针能够统计数值做累加。
(2)这里按照题目的意思是需要从右往左统计大小,所以需要用右中左的遍历顺序才可以完成题目要求,代码如下:
sumBST(root->right);
if (pre != NULL) {
root->val += pre->val;
}
pre = root;
sumBST(root->left);
(3)别忘了终止条件,是常规终止条件;
2、整体代码如下:
class Solution {
private:
// 用于存储前一个节点
TreeNode* pre;
void sumBST(TreeNode* root) {
if (root == NULL) return;
// 逆中序遍历,方便把右边的值加到左边去
sumBST(root->right);
if (pre != NULL) {
root->val += pre->val;
}
pre = root;
sumBST(root->left);
}
public:
TreeNode* convertBST(TreeNode* root) {
pre = NULL;
sumBST(root);
return root;
}
};
今日学习时间:1.5小时
leave message:
Anyone who has never made a mistake has never tried anythin new.
没有犯过错的人,也从来没有尝试过新东西。