Is binary Tree Heap
#include <bits/stdc++.h> // Includes common standard libraries (iostream, etc.)#include "Tree.h" // Assumed to contain Node class definition and buildTree function.
using namespace std; // Use the standard namespace
// Assuming Node structure from "Tree.h" is something like:/*class Node {public: int data; Node* left; Node* right; Node(int d) { this->data = d; this->left = NULL; this->right = NULL; }};Node* buildTree(Node* root) { ... } // Function to build a general binary tree*/
// Function to count the total number of nodes in a binary tree.// Required for checking the 'complete binary tree' property.// Time Complexity: O(N)// Space Complexity: O(H) (recursion stack)int countNodes(Node* root) { // Base case: If node is NULL, it has 0 nodes. if(root == NULL) { return 0; }
// Recursively count nodes in left and right subtrees, then add 1 for the current node. int left = countNodes(root->left); int right = countNodes(root->right);
return left + right + 1;}
// Function to check if a binary tree is a Complete Binary Tree (CBT).// 'root': Current node.// 'index': Hypothetical 0-based index of the current node (as if in an array representation).// 'cnt': Total number of nodes in the tree.// Time Complexity: O(N)// Space Complexity: O(H) (recursion stack)bool isCBT(Node* root, int index, int cnt) { // Base case: A NULL node is always considered part of a CBT's structure. if(root == NULL) { return true; }
// If the current node's index is out of bounds for a CBT with 'cnt' nodes, it's not a CBT. // In a CBT, all nodes from index 0 to cnt-1 must exist. if(index >= cnt) { return false; }
// Recursively check left and right children, assigning their respective array indices. // Left child: 2*index + 1 // Right child: 2*index + 2 bool left = isCBT(root->left, 2 * index + 1, cnt); bool right = isCBT(root->right, 2 * index + 2, cnt);
// Both left and right subtrees must also be valid according to CBT rules. return left && right;}
// Function to check if a binary tree satisfies the Max Heap order property.// (Parent's value >= Children's values).// Time Complexity: O(N)// Space Complexity: O(H) (recursion stack)bool isMaxOrder(Node* root) { // Base case: A NULL node or a leaf node satisfies the heap order property trivially. if(root == NULL || (root->left == NULL && root->right == NULL)) { return true; }
// If only a left child exists (valid for CBT if it's the last element). // Check if root's data is greater than its left child's data. if(root->right == NULL) { return (root->data) > (root->left->data); }
// If both children exist: // 1. Recursively check order property for left and right subtrees. bool leftOrder = isMaxOrder(root->left); bool rightOrder = isMaxOrder(root->right);
// 2. Check if current node's data is greater than both its children's data. bool currOrder = (root->data > root->left->data) && (root->data > root->right->data);
// All conditions must be true for the current subtree to satisfy Max Heap order. return leftOrder && rightOrder && currOrder;}
// Function to check if a binary tree satisfies the Min Heap order property.// (Parent's value <= Children's values).// Time Complexity: O(N)// Space Complexity: O(H) (recursion stack)bool isMinOrder(Node* root) { // Base case: A NULL node or a leaf node satisfies the heap order property trivially. if(root == NULL || (root->left == NULL && root->right == NULL)) { return true; }
// If only a left child exists. // Check if root's data is less than its left child's data. if(root->right == NULL) { return (root->data) < (root->left->data); }
// If both children exist: // 1. Recursively check order property for left and right subtrees. bool leftOrder = isMinOrder(root->left); bool rightOrder = isMinOrder(root->right);
// 2. Check if current node's data is less than both its children's data. bool currOrder = (root->data < root->left->data) && (root->data < root->right->data);
// All conditions must be true for the current subtree to satisfy Min Heap order. return leftOrder && rightOrder && currOrder;}
// Function to check if a binary tree is a Max Heap.// A tree is a Max Heap if it's a CBT AND satisfies Max Heap order.// Overall Time Complexity: O(N) (due to countNodes + traversals)bool checkMaxHeap(Node* root) { int nodeCount = countNodes(root); // Count total nodes. // Check both CBT property and Max Heap order property. return isCBT(root, 0, nodeCount) && isMaxOrder(root);}
// Function to check if a binary tree is a Min Heap.// A tree is a Min Heap if it's a CBT AND satisfies Min Heap order.// Overall Time Complexity: O(N)bool checkMinHeap(Node* root) { int nodeCount = countNodes(root); // Count total nodes. // Corrected: Must use isMinOrder for Min Heap check. return isCBT(root, 0, nodeCount) && isMinOrder(root); // <-- FIX: Changed isMaxOrder to isMinOrder}
int main() { Node* root = NULL;
// Assuming buildTree builds a general binary tree from user input. cout << "Enter data to create a binary tree (use -1 for NULL children) : "; root = buildTree(root);
// Check if it's a Max Heap. bool isMaxHeapOrder = checkMaxHeap(root); // Check if it's a Min Heap. bool isMinHeapOrder = checkMinHeap(root);
if(isMaxHeapOrder){ cout << "Given Binary Tree is a Max Heap!" << endl; } else if(isMinHeapOrder) { // Added an else if for clarity, can be just else if only one can be true. cout << "Given Binary Tree is a Min Heap!" << endl; } else { cout << "Given Binary Tree is not a Heap!" << endl; }
return 0;}
/*Example Test Cases (as provided in comments, for buildTree function):
1. Max Heap Example: Input: 40 20 10 -1 -1 15 -1 -1 25 -1 -1 Tree: 40 / \ 20 25 / \ 10 15 Output: Given Binary Tree is a Max Heap!
2. Min Heap Example: Input: 10 20 30 40 50 60 70 -1 -1 -1 -1 -1 -1 -1 -1 Tree: 10 / \ 20 30 / \ / \ 40 50 60 70 Output: Given Binary Tree is a Min Heap!
3. Not a Heap (neither Max nor Min - structural but not ordered): Input: 12 44 -1 -1 -1 Tree: 12 / 44 (Not a heap due to order: 12 < 44 for Max, but 44 has no right child for Min's strict check, and is not complete by itself) Output: Given Binary Tree is not a Heap! (Because 12 < 44, fails MaxHeap. For MinHeap, it is not complete. More accurately, for 12, left=44, right=NULL. If 12<44, it can be a min heap. But if the tree structure is: 12 / 44 Nodes: 2. Count 2. Root index 0. Left child index 1. isCBT(root=12, index=0, cnt=2): left=isCBT(44, 1, 2) -> true (since 1 < 2, and 44 has no children so it's a leaf) right=isCBT(NULL, 2, 2) -> false (because 2 >= 2) So this is NOT a CBT. Hence, not a Heap.
4. Not a Heap (Order violates): Input: 42 45 12 -1 -1 9 -1 -1 39 6 -1 -1 12 -1 -1 Tree: 42 / \ 45 39 / \ / \ 12 9 6 12 Output: Given Binary Tree is not a Heap! (Root 42 is smaller than 45, violates Max. Root 42 is larger than 12/9, violates Min.)*/
1. What is a Heap?
A Heap is a specialized tree-based data structure that satisfies two main properties:
- Complete Binary Tree (CBT): All levels of the tree are completely filled, except possibly the last level, which is filled from left to right.
- Heap Property:
- Max Heap: For any given node, its value is greater than or equal to the values of its children. (Parent $\ge$ Children)
- Min Heap: For any given node, its value is less than or equal to the values of its children. (Parent $\le$ Children)
2. Checking for Heap Properties in a Binary Tree
To determine if a general Binary Tree is a Heap, we need to verify both the “Completeness” and “Heap Order” properties.
a. Checking Completeness (isCBT
function)
- Approach: We can check completeness by traversing the tree while assigning hypothetical 0-based array indices to nodes, just like in an array representation of a complete binary tree.
- Root is at index 0.
- Left child of node at
i
is at2*i + 1
. - Right child of node at
i
is at2*i + 2
.
- Logic:
- First, count the total number of nodes in the tree (
countNodes
). - Then, traverse the tree (e.g., in pre-order) keeping track of the
index
of the current node and thetotal_count
. - If at any point, the
index
of a node is greater than or equal to thetotal_count
, it means the tree is not complete (there’s a gap or node out of bounds for a CBT). Returnfalse
. - If a node is
NULL
, it signifies a valid path within the expected structure, returntrue
. - Recursively check for left and right subtrees. All paths must be valid.
- First, count the total number of nodes in the tree (
- Time Complexity:
O(N)
(forcountNodes
andisCBT
traversal). - Space Complexity:
O(H)
(for recursion stack, where H is tree height).
b. Checking Heap Order Property (isMaxOrder
, isMinOrder
functions)
- Approach: Recursively check the value relationship between a parent and its children.
- Logic (for Max Heap Order -
isMaxOrder
):- Base Cases:
- A
NULL
node inherently satisfies the property. - A leaf node (no children) also satisfies the property trivially.
- A
- One Child Case (Left Only): If only a left child exists, check if
root->data > root->left->data
. - Two Children Case:
- Recursively call the function for both left and right subtrees.
- Additionally, check if
root->data
is greater thanroot->left->data
ANDroot->data
is greater thanroot->right->data
.
- All conditions (recursive checks and current node’s check) must be true.
- Base Cases:
- Logic (for Min Heap Order -
isMinOrder
): Same logic asisMaxOrder
, but reverse the comparison (<
instead of>
). - Time Complexity:
O(N)
. - Space Complexity:
O(H)
.
c. Combining Checks (checkMaxHeap
, checkMinHeap
functions)
- A binary tree is a Max Heap if and only if it is a Complete Binary Tree AND satisfies the Max Heap Order Property.
- A binary tree is a Min Heap if and only if it is a Complete Binary Tree AND satisfies the Min Heap Order Property.