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
Check if a given Binary Tree is Heap in Python
A binary heap is a special binary tree with two key properties: it must be a complete tree (all levels filled except possibly the last, which fills left to right), and it must satisfy the heap property (each parent node is greater than or equal to its children for a max-heap).
In this article, we'll implement a solution to check if a given binary tree satisfies both heap properties.
Understanding Heap Properties
A binary tree is a valid max-heap if:
- Complete Tree Property: All levels are completely filled except possibly the last level, which is filled from left to right
- Heap Property: Every parent node's value is greater than or equal to its children's values
Algorithm Overview
Our approach involves three helper functions:
-
number_of_nodes()− Counts total nodes in the tree -
is_complete_tree()− Checks if the tree is complete using index-based validation -
has_heap_property()− Verifies the max-heap property recursively
Implementation
class TreeNode:
def __init__(self, value):
self.val = value
self.left = None
self.right = None
def number_of_nodes(self, root):
if root is None:
return 0
else:
return (1 + self.number_of_nodes(root.left) + self.number_of_nodes(root.right))
def has_heap_property(self, root):
# Leaf node always satisfies heap property
if (root.left is None and root.right is None):
return True
# Node with only left child
if root.right is None:
return root.val >= root.left.val
# Node with both children
else:
if (root.val >= root.left.val and root.val >= root.right.val):
return (self.has_heap_property(root.left) and
self.has_heap_property(root.right))
else:
return False
def is_complete_tree(self, root, index, node_count):
# Empty tree is complete
if root is None:
return True
# If index exceeds node count, tree is not complete
if index >= node_count:
return False
# Check recursively for left and right subtrees
return (self.is_complete_tree(root.left, 2 * index + 1, node_count) and
self.is_complete_tree(root.right, 2 * index + 2, node_count))
def is_heap(self):
node_count = self.number_of_nodes(self)
if (self.is_complete_tree(self, 0, node_count) and
self.has_heap_property(self)):
return True
else:
return False
# Create the binary tree
root = TreeNode(99)
root.left = TreeNode(46)
root.right = TreeNode(39)
root.left.left = TreeNode(14)
root.left.right = TreeNode(5)
root.right.left = TreeNode(9)
root.right.right = TreeNode(33)
root.left.left.left = TreeNode(7)
root.left.left.right = TreeNode(12)
print("Is the tree a valid heap?", root.is_heap())
Is the tree a valid heap? True
How the Algorithm Works
Complete Tree Check: Uses array representation concept where for any node at index i, left child is at 2*i + 1 and right child at 2*i + 2. If any index exceeds the total node count, the tree is not complete.
Heap Property Check: Recursively verifies that each parent node's value is greater than or equal to its children's values, handling three cases: leaf nodes, nodes with only left child, and nodes with both children.
Testing with Different Cases
# Test case: Invalid heap (violates heap property)
invalid_heap = TreeNode(10)
invalid_heap.left = TreeNode(20) # Left child greater than parent
invalid_heap.right = TreeNode(15)
print("Invalid heap test:", invalid_heap.is_heap())
# Test case: Incomplete tree
incomplete_tree = TreeNode(50)
incomplete_tree.left = TreeNode(30)
incomplete_tree.right = TreeNode(40)
incomplete_tree.left.right = TreeNode(25) # Missing left child of left node
print("Incomplete tree test:", incomplete_tree.is_heap())
Invalid heap test: False Incomplete tree test: False
Time and Space Complexity
- Time Complexity: O(n) where n is the number of nodes, as we visit each node once
- Space Complexity: O(h) where h is the height of the tree due to recursion stack
Conclusion
This algorithm efficiently validates both heap properties by combining completeness checking using index-based validation and heap property verification through recursive comparison. The solution handles all edge cases including leaf nodes and incomplete trees.
