原文地址:Diameter of a Binary Tree
树的直径(有时也称作宽度),指的是树中的两个叶子节点之间最长路径的节点的数目,下面的图显示了两个树的直径都是9,形成最长路径的两个端点的叶子节点被加上了阴影(注意每个树中长度为9的路径不止一个,但是没有比9再更长的路径了)。
![这里写图片描述](https://img-blog.csdn.net/20161126152341449) 一个树T的直径是下面几条里面最长的: - T的左子树的直径 - T的右子树的直径 - 两个叶子之间穿过T的根的最长路径(这个可以通过计算这个树的子树的高度获得) 实现:
// Recursive optimized Java program to find the diameter of a
// Binary Tree
/* Class containing left and right child of current
node and key value*/
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
/* Class to print the Diameter */
class BinaryTree
{
Node root;
/* Method to calculate the diameter and return it to main */
int diameter(Node root)
{
/* base case if tree is empty */
if (root == null)
return 0;
/* get the height of left and right sub trees */
int lheight = height(root.left);
int rheight = height(root.right);
/* get the diameter of left and right subtrees */
int ldiameter = diameter(root.left);
int rdiameter = diameter(root.right);
/* Return max of following three
1) Diameter of left subtree
2) Diameter of right subtree
3) Height of left subtree + height of right subtree + 1 */
return Math.max(lheight + rheight + 1,
Math.max(ldiameter, rdiameter));
}
/* A wrapper over diameter(Node root) */
int diameter()
{
return diameter(root);
}
/*The function Compute the "height" of a tree. Height is the
number f nodes along the longest path from the root node
down to the farthest leaf node.*/
static int height(Node node)
{
/* base case tree is empty */
if (node == null)
return 0;
/* If tree is not empty then height = 1 + max of left
height and right heights */
return (1 + Math.max(height(node.left), height(node.right)));
}
public static void main(String args[])
{
/* creating a binary tree and entering the nodes */
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("The diameter of given binary tree is : "
+ tree.diameter());
}
}
时间复杂度:O(n^2)
输出:
Diameter of the given binary tree is 4
实现优化:以上实现可以通过在相同的递归,而不是分别调用height()来计算高度实现优化,感谢Amar 建议这个优化的版本。这个优化将时间减少到:O(n)。
// Recursive Java program to find the diameter of a
// Binary Tree
/* Class containing left and right child of current
node and key value*/
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
// A utility class to pass heigh object
class Height
{
int h;
}
/* Class to print the Diameter */
class BinaryTree
{
Node root;
/* define height =0 globally and call diameterOpt(root,height)
from main */
int diameterOpt(Node root, Height height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
Height lh = new Height(), rh = new Height();
if (root == null)
{
height.h = 0;
return 0; /* diameter is also 0 */
}
/* ldiameter --> diameter of left subtree
rdiameter --> Diameter of right subtree */
/* Get the heights of left and right subtrees in lh and rh
And store the returned values in ldiameter and ldiameter */
lh.h++; rh.h++;
int ldiameter = diameterOpt(root.left, lh);
int rdiameter = diameterOpt(root.right, rh);
/* Height of current node is max of heights of left and
right subtrees plus 1*/
height.h = Math.max(lh.h, rh.h) + 1;
return Math.max(lh.h + rh.h + 1, Math.max(ldiameter, rdiameter));
}
/* A wrapper over diameter(Node root) */
int diameter()
{
Height height = new Height();
return diameterOpt(root, height);
}
/*The function Compute the "height" of a tree. Height is the
number f nodes along the longest path from the root node
down to the farthest leaf node.*/
static int height(Node node)
{
/* base case tree is empty */
if (node == null)
return 0;
/* If tree is not empty then height = 1 + max of left
height and right heights */
return (1 + Math.max(height(node.left), height(node.right)));
}
public static void main(String args[])
{
/* creating a binary tree and entering the nodes */
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("The diameter of given binary tree is : "
+ tree.diameter());
}
}
时间复杂度:O(n)
输出:
4
参考文献:
http://www.cs.duke.edu/courses/spring00/cps100/assign/trees/diameter.html