Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Find the largest Complete Subtree in a given Binary Tree in Python
A complete binary tree is one where all levels are completely filled except possibly the last level, and the last level has all keys as far left as possible. In this problem, we need to find the largest complete subtree within a given binary tree and return its size.
So, if the input is like ?
Then the output will be 4 as the size, and the inorder traversal will be 10, 45, 60, 70.
Algorithm Approach
We use a recursive approach with a custom return type that tracks ?
- isComplete − whether the subtree is complete
- isPerfect − whether the subtree is perfect (completely filled)
- size − number of nodes in the largest complete subtree
- rootTree − root of the largest complete subtree
Implementation
import math
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class returnType:
def __init__(self):
self.isPerfect = None
self.isComplete = None
self.size = 0
self.rootTree = None
def getHeight(size):
return int(math.ceil(math.log(size + 1) / math.log(2)))
def checkCompleteness(root):
ret_type = returnType()
# Base case: empty tree
if root == None:
ret_type.isPerfect = True
ret_type.isComplete = True
ret_type.size = 0
ret_type.rootTree = None
return ret_type
# Recursively check left and right subtrees
left_tree = checkCompleteness(root.left)
right_tree = checkCompleteness(root.right)
# Case 1: Left is perfect, right is complete, same height
if (left_tree.isPerfect == True and right_tree.isComplete == True and
getHeight(left_tree.size) == getHeight(right_tree.size)):
ret_type.isComplete = True
ret_type.isPerfect = right_tree.isPerfect
ret_type.size = left_tree.size + right_tree.size + 1
ret_type.rootTree = root
return ret_type
# Case 2: Left is complete, right is perfect, left height = right height + 1
if (left_tree.isComplete == True and right_tree.isPerfect == True and
getHeight(left_tree.size) == getHeight(right_tree.size) + 1):
ret_type.isComplete = True
ret_type.isPerfect = False
ret_type.size = left_tree.size + right_tree.size + 1
ret_type.rootTree = root
return ret_type
# Current tree is not complete, return the larger subtree
ret_type.isPerfect = False
ret_type.isComplete = False
ret_type.size = max(left_tree.size, right_tree.size)
if left_tree.size > right_tree.size:
ret_type.rootTree = left_tree.rootTree
else:
ret_type.rootTree = right_tree.rootTree
return ret_type
def print_tree(root):
if root is not None:
print_tree(root.left)
print(root.data, end=', ')
print_tree(root.right)
# Create the binary tree
root = TreeNode(50)
root.left = TreeNode(30)
root.right = TreeNode(60)
root.left.left = TreeNode(5)
root.left.right = TreeNode(20)
root.right.left = TreeNode(45)
root.right.right = TreeNode(70)
root.right.left.left = TreeNode(10)
# Find the largest complete subtree
ans = checkCompleteness(root)
print("Size:", ans.size)
print("Inorder Traversal: ", end='')
print_tree(ans.rootTree)
Size: 4 Inorder Traversal: 10, 45, 60, 70,
How It Works
The algorithm works by checking two main conditions for a complete binary tree ?
- Left subtree is perfect, right subtree is complete with the same height
- Left subtree is complete, right subtree is perfect with left height = right height + 1
If neither condition is met, the current tree is not complete, so we return the larger complete subtree from either the left or right child.
Time Complexity
The time complexity is O(n) where n is the number of nodes, as we visit each node once. The space complexity is O(h) where h is the height of the tree due to the recursion stack.
Conclusion
This recursive approach efficiently finds the largest complete subtree by checking completeness conditions at each node. The algorithm returns both the size and root of the largest complete subtree found in the binary tree.
