654. Maximum Binary Tree(最大二叉树)

本文介绍了一种构建最大二叉树的算法实现,通过递归寻找数组中最大值作为根节点,左侧子树由左半部分数组构建,右侧子树由右半部分数组构建。该算法在速度上表现优异,运行时间为5ms,内存使用为39.9MB。

题目描述

在这里插入图片描述

方法思路

class Solution {
    //Runtime: 5 ms, faster than 100.00%
    //Memory Usage: 39.9 MB, less than 56.46%
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        TreeNode root = constructMBT_Helper(nums, 0, nums.length - 1);
        return root;
    }
    public TreeNode constructMBT_Helper(int[] nums, int start, int end){
        if(start > end) return null;
        if(start == end) return new TreeNode(nums[start]);
        int index = findMaxIndex(nums, start, end);
        TreeNode root = new TreeNode(nums[index]);
        root.left = constructMBT_Helper(nums, start, index - 1);
        root.right = constructMBT_Helper(nums, index + 1, end);
        return root;
    }
    public int findMaxIndex(int[] nums, int start, int end){
        int index = start, max = nums[start];
        for(int i = start; i <= end; i++){
            if(max < nums[i]){
                max = nums[i];
                index = i;
            }
        }
        return index;
    }
}
<think> 我们已知用户的需求是:使用C语言实现最大二叉树Maximum Binary Tree)。根据用户给出的引用内容,我们注意到引用[4]提到了“C语言实现最大二叉树并按层遍历”,但具体实现细节并未完整给出。因此,我们将结合最大二叉树的定义和常规实现方法来编写代码。 ### 最大二叉树的定义 最大二叉树的构建规则如下: 1. 创建一个根节点,其值为数组中的最大值。 2.最大值左边的子数组构建左子树(递归)。 3.最大值右边的子数组构建右子树(递归)。 ### 实现步骤 1. 在给定的数组中找到最大值及其索引。 2. 以该最大值作为根节点创建二叉树节点。 3. 递归地构建左子树(最大值左边的子数组)和右子树(最大值右边的子数组)。 ### 代码实现 下面我们将用C语言实现最大二叉树的构建,并添加按层遍历(广度优先遍历)的功能。 ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 创建新节点 TreeNode* createNode(int value) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->val = value; newNode->left = NULL; newNode->right = NULL; return newNode; } // 在数组区间[low, high]内找到最大值及其索引 int findMaxIndex(int* nums, int low, int high) { int maxIndex = low; for (int i = low+1; i <= high; i++) { if (nums[i] > nums[maxIndex]) { maxIndex = i; } } return maxIndex; } // 递归构建最大二叉树 TreeNode* constructMaximumBinaryTree(int* nums, int low, int high) { if (low > high) { return NULL; } int maxIndex = findMaxIndex(nums, low, high); TreeNode* root = createNode(nums[maxIndex]); root->left = constructMaximumBinaryTree(nums, low, maxIndex-1); root->right = constructMaximumBinaryTree(nums, maxIndex+1, high); return root; } // 按层遍历(广度优先遍历)使用队列实现 void levelOrderTraversal(TreeNode* root) { if (root == NULL) return; // 使用队列存储节点指针 TreeNode** queue = (TreeNode**)malloc(sizeof(TreeNode*)*1000); int front = 0, rear = 0; queue[rear++] = root; while (front < rear) { TreeNode* current = queue[front++]; printf("%d ", current->val); if (current->left != NULL) { queue[rear++] = current->left; } if (current->right != NULL) { queue[rear++] = current->right; } } free(queue); // 释放队列空间 } int main() { int nums[] = {3, 2, 1, 6, 0, 5}; int n = sizeof(nums) / sizeof(nums[0]); // 构建最大二叉树 TreeNode* root = constructMaximumBinaryTree(nums, 0, n-1); // 按层遍历 printf("按层遍历结果:"); levelOrderTraversal(root); printf("\n"); // 注意:实际应用中需要释放二叉树的内存,这里省略 return 0; } ``` ### 代码说明 1. **二叉树节点定义**:使用`TreeNode`结构体,包含整数值和左右子节点指针。 2. **创建节点**:`createNode`函数用于创建新节点并初始化。 3. **查找最大值索引**:`findMaxIndex`函数在数组指定区间内查找最大值索引。 4. **构建最大二叉树**:`constructMaximumBinaryTree`函数递归构建最大二叉树。 5. **按层遍历**:`levelOrderTraversal`函数使用队列实现二叉树的按层遍历。 ### 测试示例 对于输入数组:`[3,2,1,6,0,5]`,最大二叉树的构建过程如下: - 整个数组最大值为6,作为根节点。 - 左子树由`[3,2,1]`构建:最大值为3,作为根节点的左孩子;然后递归构建左子树的左右子树。 - 右子树由`[0,5]`构建:最大值为5,作为根节点的右孩子;然后递归构建右子树的左右子树。 按层遍历输出应为:`6 3 5 2 1 0`(注意:按层遍历从上到下,从左到右)。 §§ 相关问题 §§ 1. 如何优化最大二叉树的构建时间复杂度? 2. 最大二叉树有哪些应用场景? 3. 如何释放最大二叉树的内存? </think> 以下是使用C语言实现最大二叉树的完整代码和详细说明。最大二叉树是指从数组构建的二叉树,其中根节点是数组中的最大值,左子树通过最大值左侧的子数组构建,右子树通过右侧子数组构建。 ```c #include <stdio.h> #include <stdlib.h> // 二叉树节点结构 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 创建新节点 TreeNode* createNode(int value) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->val = value; newNode->left = NULL; newNode->right = NULL; return newNode; } // 在数组区间[low, high]内找到最大值索引 int findMaxIndex(int* nums, int low, int high) { int maxIndex = low; for (int i = low + 1; i <= high; i++) { if (nums[i] > nums[maxIndex]) { maxIndex = i; } } return maxIndex; } // 递归构建最大二叉树 TreeNode* constructMaximumBinaryTree(int* nums, int low, int high) { if (low > high) return NULL; // 找到当前区间最大值索引 int maxIndex = findMaxIndex(nums, low, high); // 创建根节点 TreeNode* root = createNode(nums[maxIndex]); // 递归构建左子树(最大值左侧) root->left = constructMaximumBinaryTree(nums, low, maxIndex - 1); // 递归构建右子树(最大值右侧) root->right = constructMaximumBinaryTree(nums, maxIndex + 1, high); return root; } // 按层遍历(广度优先搜索) void levelOrderTraversal(TreeNode* root) { if (!root) return; // 简易队列实现 TreeNode* queue[100]; int front = 0, rear = 0; queue[rear++] = root; while (front < rear) { TreeNode* current = queue[front++]; printf("%d ", current->val); if (current->left) queue[rear++] = current->left; if (current->right) queue[rear++] = current->right; } } int main() { // 示例输入数组 int nums[] = {3, 2, 1, 6, 0, 5}; int n = sizeof(nums) / sizeof(nums[0]); // 构建最大二叉树 TreeNode* root = constructMaximumBinaryTree(nums, 0, n - 1); // 按层遍历输出 printf("按层遍历结果: "); levelOrderTraversal(root); return 0; } ``` ### 关键实现说明: 1. **数据结构**: - 使用`TreeNode`结构体表示二叉树节点 - 包含`val`(节点值)、`left`(左子树指针)、`right`(右子树指针) 2. **核心函数**: - `findMaxIndex()`:在指定数组区间内查找最大值索引 - `constructMaximumBinaryTree()`:递归构建最大二叉树 - 时间复杂度:$O(n^2)$(最坏情况) - 空间复杂度:$O(n)$(递归栈深度) 3. **构建逻辑**: ```mermaid graph TD A[当前数组区间] --> B[查找最大值索引] B --> C[创建根节点] C --> D[递归构建左子树] C --> E[递归构建右子树] ``` 4. **示例输出**: - 输入数组:`[3,2,1,6,0,5]` - 按层遍历结果:`6 3 5 2 1 0` - 树结构: ``` 6 / \ 3 5 \ / 2 0 \ 1 ``` ### 扩展优化: 1. **时间复杂度优化**:使用线段树可将时间复杂度优化到$O(n \log n)$ 2. **内存安全**:实际使用需添加`freeTree()`函数释放内存 3. **输入处理**:可扩展为从用户输入或文件读取数组数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值