108、将有序数组转换为高度平衡二叉搜索树

此题首先可以确定选用的算法是递归

对于二叉搜索树我们可以知道其左叶子节点值<根节点值<右叶子节点值,故二叉搜索树的中序遍历为一个升序数组。即题目给的有序数组。

中序遍历:先遍历左子树,在遍历根节点,最后遍历右子树。
在这里插入图片描述
如果不要求为平衡二叉搜索树的话,仅由一个升序数组,树的根节点就有多种不同的取值,就会产生很多个不同的二叉搜索树。

如当升序数组为:[-10,-3,0,5,9]时,几种可能的情况为(还有其他情况,可以自己看一下,比较特殊):
在这里插入图片描述
如果要求为平衡二叉搜索树的话,即左右子树的最大高度差要小于等于1,所以选中的根节点左右子树的节点数量差要小于等于1,即选中升序数组的一个值其左边元素数的右边元素数的差要小于等于1。

这样就可以先求出升序数组的中间值即根节点然后左边的就为左子树,右边的为右子树,然后对左右子树再次执行相同的操作,一直递归知道最后更节点的左右子树均为空即可。

由于数组长度可能为偶数也可能为奇数,所以选择的中间值可能有差别,故最后产生的树就会不一样,这里我们采用当数组长度为奇数时,中间值即为所求,数组长度为偶数时,有两个中间值我们选取左边的为根节点(当然也可以选择右边的)。
则求得中间值的公式为:
 mid = (left+right)/2
 mid = (left+right)>>1
 mid = left+(rgiht-left)/2
以上三个公式均可,建议使用方式2,方式1当数组长度较大时肯能产生溢出带来不必要的麻烦,不过一般不会发生。

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }

    @Override
    public String toString() {
        return "TreeNode{" +
                "val=" + val +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
}
public class Test108 {

    public static void main(String[] args) {
        int[] nums = {-10,-3,0,5,9};
        Test108 test108 = new Test108();
        test108.sortedArrayToBST(nums);

    }

    //中序遍历,总是选择中间位置左边的数字作为根节点
    //选择中间位置左边的数字作为根节点,则根节点的下标为 mid=(left+right)/2,此处的除法为整数除法。
    //但是这样计算有溢出风险,使用mid = left+(right-left)/2或者移位运算较合适
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }
    public TreeNode helper(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }

        // 总是选择中间位置左边的数字作为根节点
        int mid = (left + right) / 2;
        System.out.println(left+"--"+right+"--"+mid);

        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, left, mid - 1);
        root.right = helper(nums, mid + 1, right);
        System.out.println(root);
        return root;
    }

结果为:

TreeNode{val=0, left=TreeNode{val=-10, left=null, 
									   right=TreeNode{val=-3, left=null, 
									   					        right=null}}, 
                right=TreeNode{val=5, left=null, 
                					  right=TreeNode{val=9, left=null,
                											 right=null}}}

图示:
在这里插入图片描述

选择其它位置为根节点类似,可自行推导。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将一个升序数组转换高度平衡的二搜索,可以采用递归的方式来实现。 具体步骤如下: 1. 找到数组的中间元素,作为二搜索的根节点。 2. 将数组分成左右两个子数组,左子数组中的元素都小于根节点,右子数组中的元素都大于根节点。 3. 递归地处理左右子数组,分别将它们转换为左右子。 4. 将左右子挂在根节点下,构成一棵完整的二搜索。 以下是代码示例: ```cpp #include <iostream> #include <vector> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { return buildBST(nums, 0, nums.size() - 1); } private: TreeNode* buildBST(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 = buildBST(nums, left, mid - 1); root->right = buildBST(nums, mid + 1, right); return root; } }; int main() { vector<int> nums = {1, 2, 3, 4, 5, 6, 7}; Solution solution; TreeNode* root = solution.sortedArrayToBST(nums); // 遍历打印二 return 0; } ``` 在这个示例中,我们定义了一个 `Solution` 类,其中包含了一个 `sortedArrayToBST` 函数,用于将升序数组转换高度平衡的二搜索。 我们在 `sortedArrayToBST` 函数中调用了 `buildBST` 函数,用于递归地构建二搜索。`buildBST` 函数的参数中,`nums` 表示原始数组, `left` 和 `right` 表示当前处理的数组区间。 在 `buildBST` 函数中,首先判断当前区间是否为空,如果为空则返回 `NULL`。然后计算出当前区间的中间位置 `mid`,将 `nums[mid]` 作为根节点。再递归地处理左右子数组,分别将它们转换为左右子。最后返回根节点,构成一棵完整的二搜索。 最后,我们可以使用遍历的方式打印出生成的二搜索,以验证其正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值