998. Maximum Binary Tree II(最大二叉树II)

本文探讨了在最大二叉树中插入新节点的两种方法:迭代和递归。详细解析了为何新节点总是在右侧插入,以及如何在保持树特性的同时找到正确的位置。通过代码示例展示了具体实现。

题目描述

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

方法思路

Q1:Why to the right and not to the left?
Always go right since new element will be inserted at the end of the list.
Q2:why if(root.val<v){
TreeNode node = new TreeNode(v);
node.left=root;
return node;
},rather than if(root.val<v){
TreeNode node = new TreeNode(v);
node.right=root;
return node;
};
Is it just follow the example?

Approach1: iterative
Search on the right, find the node that cur.val > val > cur.right.val
Then create new node TreeNode(val),
put old cur.right as node.left,
put node as new cur.right.

public TreeNode insertIntoMaxTree(TreeNode root, int val) {
        TreeNode node = new TreeNode(val), cur = root;
        if (root.val < val) {
            node.left = root;
            return node;
        }
        while (cur.right != null && cur.right.val > val) {
            cur = cur.right;
        }
        node.left = cur.right;
        cur.right = node;
        return root;
    }

Approach2:recursive
这道题目描述的不是很清楚感觉上。(tricky!)
The idea is to insert node to the right parent or right sub-tree of current node. Using recursion can achieve this:
If inserted value is greater than current node, the inserted goes to right parent
If inserted value is smaller than current node, we recursively re-cauculate right subtree

class Solution {
	//Runtime: 2 ms, faster than 100.00%
    //Memory Usage: 37 MB, less than 100.00% 
    public TreeNode insertIntoMaxTree(TreeNode root, int v) {
        if(root==null)return new TreeNode(v);
        if(root.val<v){
            TreeNode node = new TreeNode(v);
            node.left=root;
            return node;
        }
        root.right=insertIntoMaxTree(root.right,v);
        return root;
    }
}
<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、付费专栏及课程。

余额充值