Java实现:在二叉树中,求距离最远的两个节点的距离

方法一

思路: 递归的计算出:从每个节点出发,向左走的最大距离和向右走的最大距离,并以每个节点的这两个值为基础进一步计算和判断整个二叉树的最大距离。。。详细步骤见代码注释。


Java代码如下:

import java.util.LinkedList;
import java.util.Queue;

class Node {
	int data;
	Node left;
	Node right;
	int maxLeftLen;   // 从该节点向左走,最大距离
	int maxRightLen;  // 从该节点向右走,最大距离

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


public class Solution {
	// 用于保存树中的两个节点的最大距离
	private int maxLen = 0;

	// 使用数组建立完全二叉树
	public Node buildTree(int[] datas) {
		Queue<Node> nodeQueue = new LinkedList<Node>();
		Node root = new Node(datas[0]);
		nodeQueue.add(root);

		for (int i = 1; i < datas.length; i++) {
			// 取出队列中的第一个元素
			Node current = nodeQueue.peek();
			if (current != null) {
				if (current.left == null) {
					current.left = new Node(datas[i]);
					nodeQueue.add(current.left);
				} else {
					current.right = new Node(datas[i]);
					nodeQueue.add(current.right);
					nodeQueue.remove();
				}
			}
		}
		return root;
	}

	
	// findMaxLen能够计算出每个节点的左右子树的最大距离,并将该值+1保存在该节点的maxLeftLen和maxRightLen中
	public void findMaxLen(Node node) {
		if (node == null)
			return;
		
		// 如果该节点的左子树为空,则该从该节点向左走的最长距离为0
		if (node.left == null) {
			node.maxLeftLen = 0;
		}
		// 如果该节点的右子树为空,则该从该节点向右走的最长距离为0
		if (node.right == null) {
			node.maxRightLen = 0;
		}
		
		// 如果该节点的左子树不为空,递归的计算出该节点的左孩子节点的maxLeftLen和maxRightLen(并更新maxLen)
		if (node.left != null) {
			findMaxLen(node.left);
		}

		// 如果该节点的右子树不为空,递归的计算出该节点的右孩子节点的maxLeftLen和maxRightLen(并更新maxLen)
		if (node.right != null) {
			findMaxLen(node.right);
		}

		// 如果该节点的左子树不为空,那么该节点的maxLeftLen等于它的左孩子节点的maxLeftLen、maxRightLen中较大的那个 + 1
		if (node.left != null) {
			int maxLeftLenTemp =  Math.max(node.left.maxLeftLen, node.left.maxRightLen) + 1;
			node.maxLeftLen = maxLeftLenTemp;
		}
		// 如果该节点的右子树不为空,那么该节点的maxRightLen等于它的右孩子节点的maxLeftLen、maxRightLen中较大的那个 + 1
		if (node.right != null) {
			int maxRightLenTemp =  Math.max(node.right.maxLeftLen, node.right.maxRightLen) + 1;
			node.maxRightLen = maxRightLenTemp;
		}
		// 到这一步,当前处理的节点的maxLeftLen和maxLeftLen已经得到了,如果它的maxLeftLen+maxRightLen值比maxLen大,就可以更新maxLen
		if (maxLen < node.maxLeftLen + node.maxRightLen) {
			maxLen = node.maxLeftLen + node.maxRightLen;
		}
	}
        // 测试
	public static void main(String[] args) {
		int[] nums = {3,5,6,7};
		Solution solution = new Solution();
		Node root = solution.buildTree(nums);
		solution.findMaxLen(root);
		System.out.println(solution.maxLen);
	}
	
}


方法二:

相比于方法一,方法二的代码更为简洁。

Java代码如下:

class Node {
	int data;
	Node left;
	Node right;

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

public class Test {

	private int maxLen = 0;

	// 该方法返回从root节点出发,向左或向右所能走的最远距离(该方法的返回值并非是整个树的最远距离,而是它的左子树最远距离和右子树最远距离两者中的较大值)
	// maxLen用于保存整个二叉树的最远距离
	public int findMaxLen(Node root) {
		if (root == null) {
			return 0;
		}
		if (root.left == null && root.right == null) {
			return 0;
		}
		int leftMaxLen = findMaxLen(root.left) + 1;
		int rightMaxLen = findMaxLen(root.right) + 1;

		int maxTemp = leftMaxLen + rightMaxLen;

		if (maxTemp > maxLen) {
			maxLen = maxTemp;
		}

		return leftMaxLen > rightMaxLen ? leftMaxLen : rightMaxLen;
	}

	// 测试
	public static void main(String[] args) {
		Node node2 = new Node(2);
		Node node3 = new Node(3);
		Node node5 = new Node(5);
		Node node6 = new Node(6);
		Node node7 = new Node(7);
		Node node10 = new Node(10);
		Node node11 = new Node(11);
		Node node9 = new Node(9);
		Node node12 = new Node(12);
		Node node13 = new Node(13);
		Node node4 = new Node(4);
		
		node2.left = node3;
		node2.right = node4;
		node3.left = node5;
		node3.right = node6;
		node5.left = node7;
		node7.left = node10;
		node10.left = node11;
		node6.right = node9;
		node9.right = node12;
		node12.left = node13;
		
		Test test = new Test();
		// 从node2节点出发,向左走能走5,向右走能走1,因此返回二者中较大的值5.
		int out = test.findMaxLen(node2);
		System.out.println(out);
		// maxLen返回的才是二叉树的最远距离
		System.out.println(test.maxLen);
	}
}


下面是一段Java代码,用于找出二叉树两个节点之间的距离: ``` public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BinaryTreeDistance { public int findDistance(TreeNode root, int node1, int node2) { TreeNode lca = findLCA(root, node1, node2); int dist1 = findDistanceFromNode(lca, node1); int dist2 = findDistanceFromNode(lca, node2); return dist1 + dist2; } private TreeNode findLCA(TreeNode root, int node1, int node2) { if (root == null || root.val == node1 || root.val == node2) { return root; } TreeNode left = findLCA(root.left, node1, node2); TreeNode right = findLCA(root.right, node1, node2); if (left != null && right != null) { return root; } return left != null ? left : right; } private int findDistanceFromNode(TreeNode node, int target) { if (node == null) { return -1; } if (node.val == target) { return 0; } int left = findDistanceFromNode(node.left, target); int right = findDistanceFromNode(node.right, target); if (left == -1 && right == -1) { return -1; } else { return 1 + Math.max(left, right); } } } ``` 在上面的代码,findDistance 方法接收三个参数:根节点、目标节点 1 的值、目标节点 2 的值。该方法首先找出最近公共祖先节点(LCA),然后使用 LCA 到目标节点距离计算目标节点之间的距离。findLCA 方法通过递归遍历二叉树来查找 LCA,而 findDistanceFromNode 方法计算给定节点到目标节点距离
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值