方法:
先将这一组数据进行排序,
则可以得到索引为0~size()-1的一组有序数据
再找到这一组数据的中间的值((0+size()-1)/2索引处的值)作为根节点
再以这个中间的值为界限,区间左边部分的值作为一个新区间,被用来查找左子树的根节点,同理右边部分的值用来查找右子树的根节点
以此递归,直到区间长度为0返回
TreeNode* build(vector<int>&nums,int l,int r){
if(l>r){return nullptr;}
int mid=(l+r)/2;
TreeNode *node=new TreeNode(nums[mid]);
node->left=build(nums,l,mid-1);
node->right=build(nums,mid+1,r);
return node;
}
#将有序数组转换为二叉搜索树 这一题可用此方法解决
证明此方法的正确性:
证明的过程使用了归纳推理法
首先假设当数组长度为m和m+1时此方法可以构建平衡二叉树
那么当k=2*m+1时,也可以,证明如下:
根据上述过程,先取索引中间值作为根节点,则会将整个区间划分为长度为m的两部分
根据假设,深度为m时,此方法成立,那么左右子树为平衡二叉树
又因为左右子树相同,则此时构建出的树为平衡二叉树
当k=2*m+2时,也成立,证明如下:
同上,不过取中间值后,左子树深度为m,右子树深度为m+1
根据假设,左右子树都为平衡二叉树,因为右子树的节点数只比左子树节点数多1,
则右子树的深度最多比左子树深度大1,仍然满足平衡的条件,因此此树为平衡二叉树
当k=1和k=2时,显然成立,
那么此时因为2*m+1和2*m+2时成立,带入m=1,则k=3,4时成立,
则又可通过长度为2,3时成立推出k=5,6成立,又通过3,4成立推出k=7,8成立
由此可见,所有数都成立,此方法正确
若是题目#将二叉搜索树变平衡
想让你将一颗二叉搜索树转换成平衡二叉树 ,不再需要通过多次的左旋与右旋调整
可直接用 中序遍历此二叉树得到的数组 用此方法构建一个平衡二叉搜索树,答案会简单许多
class Solution {
public:
vector<int> nums;
void getInorder(TreeNode* root) {
if (root->left) {
getInorder(root->left);
}
nums.push_back(root->val);
if (root->right) {
getInorder(root->right);
}
}
TreeNode* build(vector<int>&nums,int l,int r){
if(l>r){return nullptr;}
int mid=(l+r)/2;
TreeNode *node=new TreeNode(nums[mid]);
temp->left=balance(nums,l,mid-1);
temp->right=balance(nums,mid+1,r);
return node;
}
TreeNode* balanceBST(TreeNode* root) {
getInorder(root);
return build(nums,0, nums.size() - 1);
}
};
vector<int> Solution::nums;