【重点】【二叉树】543. 二叉树的直径

文章讨论了两种求解二叉树直径的方法,重点介绍了一种使用DFS的简化版算法,通过全局变量避免重复计算。

题目
**首先题意就是求树的 左边深度与右边深度之和。**细节需要牢记!!!
相同套路题目:124.二叉树的最大路径和

Python

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.diameter = 0

    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        self.find(root)
        return self.diameter

    # 返回以root为根节点的直径
    def find(self, root):
        if not root:
            return 0

        leftDepth = self.find(root.left)
        rightDepth = self.find(root.right)
        self.diameter = max(leftDepth + rightDepth, self.diameter)

        return 1 + max(leftDepth, rightDepth)

Java

法1:自己想的垃圾算法

class Solution {
    public int diameterOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int curDim = maxDepth(root.left) + maxDepth(root.right);
        int leftDim = diameterOfBinaryTree(root.left);
        int rightDim = diameterOfBinaryTree(root.right);

        return Math.max(curDim, Math.max(leftDim, rightDim));
    }

    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}

法2:DFS好方法

和求二叉树中最大路径和相同套路
合理利用全局变量, 可以大大简化问题!!!

class Solution {
    int ans = 0;
    public int diameterOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        maxDepth(root);
        
        return ans;
    }

    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        ans = ans > leftDepth + rightDepth ? ans : leftDepth + rightDepth;
        return 1 + Math.max(leftDepth, rightDepth);
    }
}
<think>好的,我现在需要帮助用户解决如何使用C语言基于二叉链表实现求解二叉树最长路径的问题。用户已经提供了一些参考资料,包括二叉链表的创建和遍历方法,以及之前关于算法思路的讨论。现在我需要结合这些信息,给出一个详细的解决方案。 首先,我需要确认用户的需求。用户想要用C语言实现二叉链表结构的二叉树,并且在此基础上找到最长路径(直径)。之前的回答中提到了使用递归和深度优先搜索(DFS)的方法,现在需要将其转化为C语言的具体实现。 接下来,我需要考虑如何构建二叉链表结构的二叉树。根据引用[1],创建二叉树是通过递归实现的,输入-1表示空节点。所以在C语言中,需要定义二叉树的结构体,包含数据域和左右子节点指针。然后编写创建函数,递归地创建左右子树。 然后是关于最长路径的算法。之前的Python示例使用了一个全局变量max_length来记录最大值,但在C语言中,全局变量可能不太适合,尤其是当需要多线程或多次调用时。因此,可能需要通过指针参数或者将max_length作为函数参数来传递。不过,考虑到递归的便利性,可能还是使用静态变量或者传递指针更合适。这里可能需要定义一个辅助函数,在递归过程中更新最大值。 接下来是具体的实现步骤。首先定义二叉树的结构体,包括数据、左子树和右子树指针。然后编写创建二叉树的函数,根据用户的输入递归构建二叉树。输入-1表示空节点。 然后是计算最长路径的函数。这里需要两个步骤:计算每个节点的深度,并在过程中更新最大路径长度。递归函数depth()会返回当前节点的深度,并在每次递归时计算左右子树的深度之和,与当前的最大值比较,更新最大值。 需要注意的是,C语言中不能像Python那样在函数内部直接修改外部变量,所以需要将max_length作为指针传递,或者在辅助函数中使用静态变量。这里可能更倾向于使用指针传递,以避免静态变量的副作用。 此外,用户可能还需要释放二叉树的内存,避免内存泄漏,所以可以编写一个销毁二叉树的函数,递归释放每个节点。 测试部分,用户需要输入二叉树的数据,例如按照先序遍历的顺序输入节点值,-1表示空节点。例如,输入1 2 4 -1 -1 5 -1 -1 3 -1 -1,构建示例中的二叉树,然后计算最长路径是否为3。 还需要考虑如何处理用户输入错误的情况,但根据问题描述,可能暂时不需要处理,重点放在算法实现上。 总结步骤: 1. 定义二叉树结构体。 2. 实现二叉树的创建函数。 3. 实现计算最长路径的递归函数,更新最大值。 4. 编写主函数,测试创建和计算过程。 5. 实现销毁函数,释放内存。 在实现递归函数时,需要注意递归的终止条件(节点为空时返回深度0),然后递归计算左右子树的深度,并更新当前的最大路径长度。每次递归返回当前节点的最大深度加1。 最后,验证示例是否正确,确保代码能够正确处理各种情况,包括单节点、左斜树、右斜树等边界情况。</think>### C语言二叉链表实现二叉树最长路径算法 --- #### **一、数据结构定义** 使用二叉链表存储结构,每个节点包含数据域、左子树指针、右子树指针: ```c typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; ``` --- #### **二、二叉树创建(递归实现)** 根据输入规则(输入-1表示空节点)构建二叉树[^1]: ```c TreeNode* createTree() { int val; scanf("%d", &val); if (val == -1) return NULL; TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->val = val; node->left = createTree(); // 递归创建左子树 node->right = createTree(); // 递归创建右子树 return node; } ``` --- #### **三、最长路径算法实现** ##### **核心逻辑** 1. **递归计算子树深度**:后序遍历计算左右子树深度 2. **动态更新最长路径**:最长路径 = max(左深度 + 右深度) ##### **代码实现** ```c int max(int a, int b) { return a > b ? a : b; } int depth(TreeNode* root, int* maxDiameter) { if (!root) return 0; int leftDepth = depth(root->left, maxDiameter); int rightDepth = depth(root->right, maxDiameter); // 更新最长路径 *maxDiameter = max(*maxDiameter, leftDepth + rightDepth); // 返回当前子树深度 return max(leftDepth, rightDepth) + 1; } int findLongestPath(TreeNode* root) { int maxDiameter = 0; depth(root, &maxDiameter); return maxDiameter; } ``` --- #### **四、内存释放(递归销毁)** ```c void destroyTree(TreeNode* root) { if (!root) return; destroyTree(root->left); destroyTree(root->right); free(root); } ``` --- #### **五、完整测试代码** ```c #include <stdio.h> #include <stdlib.h> typedef struct TreeNode {/* 结构体定义同上 */} TreeNode* createTree() {/* 同上 */} int depth(TreeNode* root, int* maxDiameter) {/* 同上 */} int findLongestPath(TreeNode* root) {/* 同上 */} void destroyTree(TreeNode* root) {/* 同上 */} int main() { printf("输入二叉树先序序列(-1表示空节点):\n"); TreeNode* root = createTree(); int result = findLongestPath(root); printf("最长路径长度: %d\n", result); destroyTree(root); return 0; } ``` --- #### **六、示例验证** 输入二叉树: ``` 1 / \ 2 3 / \ 4 5 ``` 输入序列:`1 2 4 -1 -1 5 -1 -1 3 -1 -1` 输出结果:`最长路径长度: 3` --- #### **七、关键点解析** 1. **递归控制**:`depth()`函数既计算深度又更新最长路径 2. **指针传参**:通过`int* maxDiameter`传递最长路径值,避免全局变量 3. **时间复杂度**:$$O(n)$$,每个节点仅访问一次[^1] --- #### **八、引用说明** [^1]: 二叉链表创建方法参考递归实现与指针操作规范 [^2]: 非递归遍历算法可通过栈实现,但本算法无需显式遍历整树 --- #### **相关问题** 1. 如何记录最长路径的具体节点序列? 2. 如何处理带权二叉树的最大路径和问题? 3. 非递归实现中如何避免栈溢出的风险?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值