The diameter/width of a tree is defined as the number of nodes on the longest path between two end nodes.
The diagram below shows two trees each with a diameter of nine, the leaves that form the ends of the longest path are shaded (note that there is more than one path in each tree of length nine, but no path longer than nine nodes).

Approach: The diameter of a tree T is the largest of the following quantities:
- the diameter of T’s left subtree.
- the diameter of T’s right subtree.
- the longest path between leaves that goes through the root of T (this can be computed from the heights of the subtrees of T)
Below is the implementation of the above approach
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node *left, *right;
};
struct node* newNode( int data);
int max( int a, int b) { return (a > b) ? a : b; }
int height( struct node* node);
int diameter( struct node* tree)
{
if (tree == NULL)
return 0;
int lheight = height(tree->left);
int rheight = height(tree->right);
int ldiameter = diameter(tree->left);
int rdiameter = diameter(tree->right);
return max(lheight + rheight + 1,
max(ldiameter, rdiameter));
}
int height( struct node* node)
{
if (node == NULL)
return 0;
return 1 + max(height(node->left), height(node->right));
}
struct node* newNode( int data)
{
struct node* node
= ( struct node*) malloc ( sizeof ( struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
int main()
{
struct node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
cout << "Diameter of the given binary tree is "
<< diameter(root);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *left, *right;
};
struct node* newNode( int data);
int max( int a, int b) { return (a > b) ? a : b; }
int height( struct node* node);
int diameter( struct node* tree)
{
if (tree == NULL)
return 0;
int lheight = height(tree->left);
int rheight = height(tree->right);
int ldiameter = diameter(tree->left);
int rdiameter = diameter(tree->right);
return max(lheight + rheight + 1,
max(ldiameter, rdiameter));
}
int height( struct node* node)
{
if (node == NULL)
return 0;
return 1 + max(height(node->left), height(node->right));
}
struct node* newNode( int data)
{
struct node* node
= ( struct node*) malloc ( sizeof ( struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
int main()
{
struct node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf ( "Diameter of the given binary tree is %d\n" ,
diameter(root));
return 0;
}
|
Java
class Node {
int data;
Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
int diameter(Node root)
{
if (root == null )
return 0 ;
int lheight = height(root.left);
int rheight = height(root.right);
int ldiameter = diameter(root.left);
int rdiameter = diameter(root.right);
return Math.max(lheight + rheight + 1 ,
Math.max(ldiameter, rdiameter));
}
int diameter() { return diameter(root); }
static int height(Node node)
{
if (node == null )
return 0 ;
return ( 1
+ Math.max(height(node.left),
height(node.right)));
}
public static void main(String args[])
{
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());
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def height(node):
if node is None :
return 0
return 1 + max (height(node.left), height(node.right))
def diameter(root):
if root is None :
return 0
lheight = height(root.left)
rheight = height(root.right)
ldiameter = diameter(root.left)
rdiameter = diameter(root.right)
return max (lheight + rheight + 1 , max (ldiameter, rdiameter))
if __name__ = = "__main__" :
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.left.left = Node( 4 )
root.left.right = Node( 5 )
print (diameter(root))
|
C#
using System;
namespace Tree {
class Tree<T> {
public Tree(T value) { this .value = value; }
public T value
{
get ;
set ;
}
public Tree<T> left
{
get ;
set ;
}
public Tree<T> right
{
get ;
set ;
}
}
public class TreeDiameter {
Tree< int > root;
int Height(Tree< int > node)
{
if (node == null )
return 0;
return 1
+ Math.Max(Height(node.left),
Height(node.right));
}
int Diameter(Tree< int > root)
{
if (root == null )
return 0;
int lHeight = Height(root.left);
int rHeight = Height(root.right);
int lDiameter = Diameter(root.left);
int rDiameter = Diameter(root.right);
return Math.Max(lHeight + rHeight + 1,
Math.Max(lDiameter, rDiameter));
}
int Diameter() { return Diameter(root); }
public static void Main( string [] args)
{
TreeDiameter tree = new TreeDiameter();
tree.root = new Tree< int >(1);
tree.root.left = new Tree< int >(2);
tree.root.right = new Tree< int >(3);
tree.root.left.left = new Tree< int >(4);
tree.root.left.right = new Tree< int >(5);
Console.WriteLine(
"The diameter of given binary tree is : "
+ tree.Diameter());
}
}
}
|
Javascript
<script>
class Node{
constructor(data){
this .data = data
this .left = null
this .right = null
}
}
function height(node)
{
if (node == null )
return 0
return 1 + Math.max(height(node.left), height(node.right))
}
function diameter(root){
if (root == null )
return 0
let lheight = height(root.left)
let rheight = height(root.right)
let ldiameter = diameter(root.left)
let rdiameter = diameter(root.right)
return Math.max(lheight + rheight + 1, Math.max(ldiameter, rdiameter))
}
root = new Node(1)
root.left = new Node(2)
root.right = new Node(3)
root.left.left = new Node(4)
root.left.right = new Node(5)
document.write( "Diameter of the given binary tree is " +diameter(root))
</script>
|
OutputDiameter of the given binary tree is 4
Time Complexity: O(N2)
Auxiliary Space: O(N) for call stack
Efficient Approach: To solve the problem follow the below idea:
The above implementation can be optimized by calculating the height in the same recursion rather than calling a height() separately. Thanks to Amar for suggesting this optimized version.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node *left, *right;
};
struct node* newNode( int data);
int diameterOpt( struct node* root, int * height)
{
int lh = 0, rh = 0;
int ldiameter = 0, rdiameter = 0;
if (root == NULL) {
*height = 0;
return 0;
}
ldiameter = diameterOpt(root->left, &lh);
rdiameter = diameterOpt(root->right, &rh);
*height = max(lh, rh) + 1;
return max(lh + rh + 1, max(ldiameter, rdiameter));
}
struct node* newNode( int data)
{
struct node* node
= ( struct node*) malloc ( sizeof ( struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
int main()
{
struct node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
int height = 0;
cout << "Diameter of the given binary tree is "
<< diameterOpt(root, &height);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class Height {
int h;
}
class BinaryTree {
Node root;
int diameterOpt(Node root, Height height)
{
Height lh = new Height(), rh = new Height();
if (root == null ) {
height.h = 0 ;
return 0 ;
}
int ldiameter = diameterOpt(root.left, lh);
int rdiameter = diameterOpt(root.right, rh);
height.h = Math.max(lh.h, rh.h) + 1 ;
return Math.max(lh.h + rh.h + 1 ,
Math.max(ldiameter, rdiameter));
}
int diameter()
{
Height height = new Height();
return diameterOpt(root, height);
}
static int height(Node node)
{
if (node == null )
return 0 ;
return ( 1
+ Math.max(height(node.left),
height(node.right)));
}
public static void main(String args[])
{
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());
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = self .right = None
class Height:
def __init( self ):
self .h = 0
def diameterOpt(root, height):
lh = Height()
rh = Height()
if root is None :
height.h = 0
return 0
ldiameter = diameterOpt(root.left, lh)
rdiameter = diameterOpt(root.right, rh)
height.h = max (lh.h, rh.h) + 1
return max (lh.h + rh.h + 1 , max (ldiameter, rdiameter))
def diameter(root):
height = Height()
return diameterOpt(root, height)
if __name__ = = "__main__" :
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.left.left = Node( 4 )
root.left.right = Node( 5 )
print ( "The diameter of the binary tree is:" , end = " " )
print (diameter(root))
|
C#
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class Height {
public int h;
}
class BinaryTree {
public Node root;
public int diameterOpt(Node root, Height height)
{
Height lh = new Height(), rh = new Height();
if (root == null ) {
height.h = 0;
return 0;
}
int ldiameter = diameterOpt(root.left, lh);
int rdiameter = diameterOpt(root.right, rh);
height.h = Math.Max(lh.h, rh.h) + 1;
return Math.Max(lh.h + rh.h + 1,
Math.Max(ldiameter, rdiameter));
}
public int diameter()
{
Height height = new Height();
return diameterOpt(root, height);
}
public int height(Node node)
{
if (node == null )
return 0;
return (1
+ Math.Max(height(node.left),
height(node.right)));
}
static void Main()
{
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);
Console.Write(
"The diameter of given binary tree is : "
+ tree.diameter());
}
}
|
Javascript
<script>
class Node{
constructor(data){
this .data = data
this .left = this .right = null
}
}
class Height
{
constructor()
{
this .h = 0
}
}
function diameterOpt(root, height){
let lh = new Height()
let rh = new Height()
if (root == null )
{
height.h = 0
return 0
}
let ldiameter = diameterOpt(root.left, lh)
let rdiameter = diameterOpt(root.right, rh)
height.h = Math.max(lh.h, rh.h) + 1
return Math.max(lh.h + rh.h + 1, Math.max(ldiameter, rdiameter))
}
function diameter(root){
let height = new Height()
return diameterOpt(root, height)
}
let root = new Node(1)
root.left = new Node(2)
root.right = new Node(3)
root.left.left = new Node(4)
root.left.right = new Node(5)
document.write(diameter(root))
</script>
|
OutputDiameter of the given binary tree is 4
Time Complexity: O(N)
Auxiliary Space: O(N) due to recursive calls.
An Efficient Approach To Solve This Problem “Using Morris Traversal Algorithm”:

Follow the steps below to implement above idea:
- Define a struct or class for a binary tree node that contains data, a pointer to its left child, and a pointer to its right child.
- Define a function to create a new node with a given data value and set its left and right child pointers to NULL.
- Define a function to calculate the maximum of two integers.
- Define a function to calculate the diameter of a binary tree using the Morris Traversal algorithm.
- Initialize the current node as the root of the binary tree.
- While the current node is not NULL, do the following:
a. If the left child of the current node is NULL, move to the right child.
b. If the left child of the current node is not NULL, find the rightmost node in the left subtree of the current node.
c. If the right child of the rightmost node is NULL, set its right child to the current node, and move to the left child of the current node.
d. If the right child of the rightmost node is not NULL, set its right child back to NULL, visit the current node, and move to its right child.
e. For each visited node, calculate its left and right subtree heights using the maximum function and update the diameter as the maximum of the sum of their heights and the current diameter. - Return the diameter of the binary tree.
Below is the implementation of the above approach:
C++
#include <algorithm>
#include <iostream>
using namespace std;
struct Node {
int data;
struct Node* left;
struct Node* right;
};
Node* newNode( int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return (node);
}
int findDiameter(Node* root)
{
int ans = 0;
Node* curr = root;
while (curr != NULL) {
if (curr->left == NULL) {
curr = curr->right;
}
else {
Node* pre = curr->left;
while (pre->right != NULL && pre->right != curr)
pre = pre->right;
if (pre->right == NULL) {
pre->right = curr;
curr = curr->left;
}
else {
pre->right = NULL;
int leftHeight = 0, rightHeight = 0;
Node* temp = curr->left;
while (temp != NULL) {
leftHeight++;
temp = temp->right;
}
temp = curr->right;
while (temp != NULL) {
rightHeight++;
temp = temp->left;
}
ans = max(ans,
leftHeight + rightHeight + 1);
curr = curr->right;
}
}
}
return ans;
}
int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
int diameter = findDiameter(root);
cout << "The diameter of given binary tree is "
<< diameter << endl;
return 0;
}
|
Java
class Node {
int data;
Node left, right;
public Node( int data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
public class Main
{
public static Node newNode( int data) {
Node node = new Node(data);
return node;
}
public static int findDiameter(Node root) {
int ans = 0 ;
Node curr = root;
while (curr != null ) {
if (curr.left == null ) {
curr = curr.right;
} else {
Node pre = curr.left;
while (pre.right != null && pre.right != curr) {
pre = pre.right;
}
if (pre.right == null ) {
pre.right = curr;
curr = curr.left;
} else {
pre.right = null ;
int leftHeight = 0 , rightHeight = 0 ;
Node temp = curr.left;
while (temp != null ) {
leftHeight++;
temp = temp.right;
}
temp = curr.right;
while (temp != null ) {
rightHeight++;
temp = temp.left;
}
ans = Math.max(ans, leftHeight + rightHeight + 1 );
curr = curr.right;
}
}
}
return ans;
}
public static void main(String[] args)
{
Node root = newNode( 1 );
root.left = newNode( 2 );
root.right = newNode( 3 );
root.left.left = newNode( 4 );
root.left.right = newNode( 5 );
int diameter = findDiameter(root);
System.out.println( "The diameter of given binary tree is " + diameter);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def newNode(data):
node = Node(data)
return node
def findDiameter(root):
ans = 0
curr = root
while curr is not None :
if curr.left is None :
curr = curr.right
else :
pre = curr.left
while pre.right is not None and pre.right ! = curr:
pre = pre.right
if pre.right is None :
pre.right = curr
curr = curr.left
else :
pre.right = None
leftHeight = 0
rightHeight = 0
temp = curr.left
while temp is not None :
leftHeight + = 1
temp = temp.right
temp = curr.right
while temp is not None :
rightHeight + = 1
temp = temp.left
ans = max (ans, leftHeight + rightHeight + 1 )
curr = curr.right
return ans
if __name__ = = '__main__' :
root = newNode( 1 )
root.left = newNode( 2 )
root.right = newNode( 3 )
root.left.left = newNode( 4 )
root.left.right = newNode( 5 )
diameter = findDiameter(root)
print ( "The diameter of given binary tree is" , diameter)
|
C#
using System;
public class Node {
public int data;
public Node left;
public Node right;
public Node( int data)
{
this .data = data;
this .left = null ;
this .right = null ;
}
}
public class Program {
public static Node newNode( int data)
{
Node node = new Node(data);
return node;
}
public static int findDiameter(Node root)
{
int ans = 0;
Node curr = root;
while (curr != null ) {
if (curr.left == null ) {
curr = curr.right;
}
else {
Node pre = curr.left;
while (pre.right != null
&& pre.right != curr) {
pre = pre.right;
}
if (pre.right == null ) {
pre.right = curr;
curr = curr.left;
}
else {
pre.right = null ;
int leftHeight = 0, rightHeight = 0;
Node temp = curr.left;
while (temp != null ) {
leftHeight++;
temp = temp.right;
}
temp = curr.right;
while (temp != null ) {
rightHeight++;
temp = temp.left;
}
ans = Math.Max(
ans, leftHeight + rightHeight + 1);
curr = curr.right;
}
}
}
return ans;
}
public static void Main()
{
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
int diameter = findDiameter(root);
Console.WriteLine(
"The diameter of given binary tree is "
+ diameter);
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function newNode(data) {
let node = new Node(data);
return node;
}
function findDiameter(root) {
let ans = 0;
let curr = root;
while (curr != null ) {
if (curr.left == null ) {
curr = curr.right;
} else {
let pre = curr.left;
while (pre.right != null && pre.right != curr) {
pre = pre.right;
}
if (pre.right == null ) {
pre.right = curr;
curr = curr.left;
} else {
pre.right = null ;
let leftHeight = 0, rightHeight = 0;
let temp = curr.left;
while (temp != null ) {
leftHeight++;
temp = temp.right;
}
temp = curr.right;
while (temp != null ) {
rightHeight++;
temp = temp.left;
}
ans = Math.max(ans, leftHeight + rightHeight + 1);
curr = curr.right;
}
}
}
return ans;
}
let root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
let diameter = findDiameter(root);
console.log( "The diameter of given binary tree is " + diameter);
|
OutputThe diameter of given binary tree is 4
Time Complexity: O(N),, where N is the number of nodes in the binary tree
Auxiliary Space: O(h),The Morris Traversal approach does not use any additional data structures like stacks or queues, which leads to an auxiliary space complexity of O(1). However, the recursion stack used by the program contributes to a space complexity of O(h), where h is the height of the binary tree.
Related Article:
Diameter of a Binary Tree in O(n) [A new method]
Diameter of an N-ary tree
Please write comments if you find any of the above codes/algorithms incorrect, or find other ways to solve the same problem.