二叉树最长路径

本文探讨了在二叉树中寻找最长路径的算法,详细解释了递归过程中的三种可能情况,包括路径完全位于左子树、右子树,或是跨越根节点连接左右子树。通过定义结点类和返回类型,文章提供了两种实现方式,一种使用自定义返回类型,另一种采用全局数组优化计算。

分析:

暴力求每一段距离也可。

 

对于以本节点为根的二叉树,最远距离有三种可能:

1)最远路径来自左子树

2 )最远路径来自右子树(图示与左子树同理)

3)最远路径为左右子树距离根最远的两个节点,经过根结点连起来。

(多种最长路径)

 

需要的信息:

1)左子树的最远路径长度

2)右子树的最远路径长度

3)左右子树的深度(深度即最远节点)

 

定义结点:

    public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

构造返回值信息:

    public static class ReturnType{
		public int maxDistance;//最长距离
		public int h;          //高度
		
		public ReturnType(int m, int h) {
			this.maxDistance = m;;
			this.h = h;
		}
	}

求解过程比较好写了:

	public static ReturnType process(Node head) {
		if(head == null) {
			return new ReturnType(0,0);
		}
		//收信息
		ReturnType leftReturnType = process(head.left);
		ReturnType rightReturnType = process(head.right);
		
		int includeHeadDistance = leftReturnType.h + 1 + rightReturnType.h;//情况3
		int p1 = leftReturnType.maxDistance;
		int p2 = rightReturnType.maxDistance;
		
		int resultDistance = Math.max(Math.max(p1, p2), includeHeadDistance);//最长距离
		int hitself  = Math.max(leftReturnType.h, leftReturnType.h) + 1;     //树的高度等于子树高度+1
		
		return new ReturnType(resultDistance, hitself);
	}

优化:

其实我们不需要返回左右子树深度,可以用一个全局变量记录。遇到NULL把变量记为0,不影响接下来的计算。

用一个含一个元素的数组来记录。因为某些二叉树题目不只需要一个信息,所以要利用全局数组。

	public static int posOrder(Node head, int[] record) {
		if (head == null) {
			record[0] = 0;//重要
			return 0;
		}
		//取信息
		int lMax = posOrder(head.left, record);
		int maxfromLeft = record[0];
		int rMax = posOrder(head.right, record);
		int maxFromRight = record[0];
		
		int curNodeMax = maxfromLeft + maxFromRight + 1;//情况3
		record[0] = Math.max(maxfromLeft, maxFromRight) + 1;
		
		return Math.max(Math.max(lMax, rMax), curNodeMax);
	}

最后放上全部代码:

package q;

public class Demo {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static int maxDistance(Node head) {
		int[] record = new int[1];
		return posOrder(head, record);
	}
	
	public static class ReturnType{
		public int maxDistance;//最长距离
		public int h;          //高度
		
		public ReturnType(int m, int h) {
			this.maxDistance = m;;
			this.h = h;
		}
	}
	
	public static ReturnType process(Node head) {
		if(head == null) {
			return new ReturnType(0,0);
		}
		//收信息
		ReturnType leftReturnType = process(head.left);
		ReturnType rightReturnType = process(head.right);
		
		int includeHeadDistance = leftReturnType.h + 1 + rightReturnType.h;//情况3
		int p1 = leftReturnType.maxDistance;
		int p2 = rightReturnType.maxDistance;
		
		int resultDistance = Math.max(Math.max(p1, p2), includeHeadDistance);//最长距离
		int hitself  = Math.max(leftReturnType.h, leftReturnType.h) + 1;     //树的高度等于子树高度+1
		
		return new ReturnType(resultDistance, hitself);
	}

	public static int posOrder(Node head, int[] record) {
		if (head == null) {
			record[0] = 0;//重要
			return 0;
		}
		//取信息
		int lMax = posOrder(head.left, record);
		int maxfromLeft = record[0];
		int rMax = posOrder(head.right, record);
		int maxFromRight = record[0];
		
		int curNodeMax = maxfromLeft + maxFromRight + 1;//情况3
		record[0] = Math.max(maxfromLeft, maxFromRight) + 1;
		
		return Math.max(Math.max(lMax, rMax), curNodeMax);
	}

	public static void main(String[] args) {
		Node head1 = new Node(1);
		head1.left = new Node(2);
		head1.right = new Node(3);
		head1.left.left = new Node(4);
		head1.left.right = new Node(5);
		head1.right.left = new Node(6);
		head1.right.right = new Node(7);
		head1.left.left.left = new Node(8);
		head1.right.left.right = new Node(9);
		System.out.println(maxDistance(head1));

		Node head2 = new Node(1);
		head2.left = new Node(2);
		head2.right = new Node(3);
		head2.right.left = new Node(4);
		head2.right.right = new Node(5);
		head2.right.left.left = new Node(6);
		head2.right.right.right = new Node(7);
		head2.right.left.left.left = new Node(8);
		head2.right.right.right.right = new Node(9);
		System.out.println(maxDistance(head2));

	}

}

 

### 关于二叉树最长路径的C语言实现 在解决二叉树最长路径的问题时,通常可以通过递归方法来完成。以下是基于引用内容以及专业知识设计的一个完整的解决方案。 #### 定义二叉树结构 首先定义二叉树的数据结构如下: ```c typedef char ElemType; typedef struct BinNode { ElemType data; struct BinNode *lchild, *rchild; } BinNode, *BinTree; ``` 此部分来源于对二叉树基本结构的理解[^4]。 --- #### 计算二叉树的高度(间接用于最长路径) 为了找到最长路径,我们需要知道二叉树的高度。通过递归函数 `GetHeight` 可以获取某一节点的高度: ```c int GetHeight(BinTree root) { if (root == NULL) return 0; int leftHeight = GetHeight(root->lchild); int rightHeight = GetHeight(root->rchild); return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } ``` 上述代码实现了计算某个节点高度的功能,这是后续寻找最长路径的基础之一[^5]。 --- #### 寻找最长路径的核心逻辑 对于一条路径而言,其可能经过根节点或者完全位于左子树/右子树内部。因此我们采用后序遍历的方式,在访问当前节点之前先处理它的左右孩子,并记录下每条路径上的最大值。 下面展示了一个具体的算法框架及其解释说明: ```c #include <stdio.h> #include <stdlib.h> // 声明全局变量 maxPathLength 来保存最终的结果 static int maxPathLength; void FindLongestPathUtil(BinTree node, int currentLength) { if (!node) { // 如果到达空节点,则更新最大长度并返回 if (currentLength > maxPathLength) { maxPathLength = currentLength; } return; } // 当前层的操作:增加路径长度计数器 currentLength++; // 对左右子树分别调用FindLongestPathUtil 函数继续探索更深层次 FindLongestPathUtil(node->lchild, currentLength); FindLongestPathUtil(node->rchild, currentLength); } void FindLongestPath(BinTree root){ maxPathLength=0;// 初始化最大路径长度为零 FindLongestPathUtil(root,0);// 调用辅助函数开始搜索过程 } ``` 以上代码片段展示了如何利用递归来追踪从根至叶的不同路径,并动态维护一个表示已知最远距离的整型数值maxPathLength 。每当遇到新的更深的位置就刷新这个纪录直到整个树都被扫描完毕为止[^1]。 注意这里并没有直接输出具体哪几个结点构成了所谓的“最长”,如果还需要额外提供这样的信息的话则需稍作修改加入相应的存储机制比如数组之类的容器类型用来暂存沿途所经之处的信息以便最后呈现出来。 --- ### 性能分析与注意事项 这种方法的时间复杂度主要取决于它要执行多少次基础操作——即每次都要比较两个孩子的高低然后加一再传回去给上级调用者;而空间消耗方面由于采用了标准形式的递归所以会占用一定的堆栈资源量级大约等于O(h),其中h代表目标二叉树的实际高矮程度[^3]。 另外值得注意的是本方案默认输入已经构建好的一棵合法有效的二叉链接列表作为起点参数传递进来,实际应用当中也许需要考虑更多边界情况例如非法指针指向NULL等问题预防潜在崩溃风险发生。 ---
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值