Check if a Binary Tree is an Even-Odd Tree or not


Even-Odd Tree − A binary tree is called an even-odd tree if all the nodes at the even level (taking root node at level 0) have even values and all the nodes at the odd level have odd values.

Problem Statement

Given a binary tree. The task is to check if the binary tree is an even-odd tree or not.

Sample Example 1

Input

       6
      / \
     3   7
    /     \
   2       8
  / \     /
 11  3   9

Output

True

Explanation

  • Level 0(even) = Node value is 6 -> even

  • Level 1(odd) = Node values are 3 -> odd and 7 -> odd

  • Level 2(even) = Node values are 2 -> even and 8 -> even

  • Level 3(odd) = Node values are 11 -> odd, 3 -> odd and 9 -> odd

So, the given tree is an even-odd tree.

Sample Example 2

Input

       5
      / \
     4   7
    /
   2

Output

False

Explanation

  • Level 0(even) = Node value is 5 -> odd - False

  • Level 1(odd) = Node values are 4 -> even and 7 -> odd - False

  • Level 2(even) = Node value is 2 -> even

So, the given tree is not an even-odd tree.

Approach 1: Depth-First Search (DFS) Approach

DFS solution to the problem is to check at each level of the search of the tree the node values. If the node values and level for all nodes are both even or both odd, then return true else false.

Pseudocode

isEvenOddTree(node, level):
   if node is null:
      return true
    
   # Check if the node's value is valid for its level
   if level is even:
      if node.value is not even:
         return false
   else:
      if node.value is not odd:
         return false

   # Recursively check the left and right subtrees
   leftResult = isEvenOddTree(node.left, level + 1)
   rightResult = isEvenOddTree(node.right, level + 1)

   return leftResult and rightResult

isEvenOddTree(root):
   return isEvenOddTree(root, 0)

Example: C++ Implementation

Below is the C++ Implemention of the proposed DFS solution.

#include <iostream>
using namespace std;

struct TreeNode {
   int val;
   TreeNode* left;
   TreeNode* right;
   TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};

bool is_even_odd_tree_helper(TreeNode* node, int level){
   if (!node) {
      return true;
   }
   // Check if the node's value is valid for its level
   if (level % 2 == 0) { // Even level
      if (node->val % 2 != 0) {
         return false;
      }
   } else { // Odd level
      if (node->val % 2 == 0) {
         return false;
      }
   }
   // Recursively check the left and right subtrees
   return is_even_odd_tree_helper(node->left, level + 1) &&
   is_even_odd_tree_helper(node->right, level + 1);
}

bool is_even_odd_tree(TreeNode* root){
   return is_even_odd_tree_helper(root, 0);
}
int main(){
   // Test case:
   //       4
   //      / \
   //     3   7
   //    / \   \
   //   4  6    2
   TreeNode* root = new TreeNode(4);
   root->left = new TreeNode(3);
   root->right = new TreeNode(7);
   root->left->left = new TreeNode(4);
   root->left->right = new TreeNode(6);
   root->right->right = new TreeNode(2);
   if (is_even_odd_tree(root)) {
      std::cout << "The tree is an Even-Odd Tree.\n";
   } else {
      std::cout << "The tree is NOT an Even-Odd Tree.\n";
   }
   // Clean up memory
   delete root->left->left;
   delete root->left->right;
   delete root->right->left;
   delete root->right->right;
   delete root->left;
   delete root->right;
   delete root;
   return 0;
}

Output

The tree is an Even-Odd Tree.

Time Complexity − O(N), where N is the number of nodes in binary tree.

Space Complexity − O(N), where N is the number of nodes in binary tree.

Approach 2: Breadth-First Search (BFS) Approach

BFS solution to the problem is to check at each level of the search of the tree the node values. If the node values and level for all nodes are both even or both odd, then return true else false.

Pseudocode −

function is_even_odd_tree(root):
   if root is null:
      return true

   queue = Queue()
   queue.push(root)
   is_even_level = true

   while queue is not empty:
      level_size = queue.size()
      prev_val = INT_MIN if is_even_level else INT_MAX

      for i from 0 to level_size - 1:
         node = queue.front()
         queue.pop()

         // Check if the node's value is valid for its level
         if is_even_level:  // Even level
            if node.val is odd:
               return false
         else:  // Odd level
            if node.val is even:
               return false

         prev_val = node.val

         if node.left is not null:
            queue.push(node.left)

         if node.right is not null:
            queue.push(node.right)

      is_even_level = not is_even_level

   return true

Example: C++ Implemention

Below is the C++ Implemention of the proposed BFS solution.

#include <iostream>
#include <queue>
#include <climits>
using namespace std;

struct TreeNode {
   int val;
   TreeNode* left;
   TreeNode* right;
   TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};
bool is_even_odd_tree(TreeNode* root){
   if (!root) {
      return true;
   }
   std::queue<TreeNode*> q;
   q.push(root);
   bool is_even_level = true;
   while (!q.empty()) {
      int level_size = q.size();
      int prev_val = is_even_level ? INT_MIN : INT_MAX;
      for (int i = 0; i < level_size; ++i) {
         TreeNode* node = q.front();
         q.pop();
         // Check if the node's value is valid for its level
         if (is_even_level) { // Even level
            if (node->val % 2 != 0) {
               return false;
            }
         } else { // Odd level
            if (node->val % 2 == 0) {
               return false;
            }
         }
         prev_val = node->val;
         if (node->left) {
            q.push(node->left);
         }
         if (node->right) {
            q.push(node->right);
         }
      }
      is_even_level = !is_even_level;
   }
   return true;
}
int main(){
   // Test case:
   //       4
   //      / \
   //     3   7
   //    / \  / \
   //   2  8 8  21
   TreeNode* root = new TreeNode(4);
   root->left = new TreeNode(3);
   root->right = new TreeNode(7);
   root->left->left = new TreeNode(2);
   root->left->right = new TreeNode(8);
   root->right->left = new TreeNode(8);
   root->right->right = new TreeNode(21);
   if (is_even_odd_tree(root)) {
      std::cout << "The tree is an Even-Odd Tree.\n";
   } else {
      std::cout << "The tree is NOT an Even-Odd Tree.\n";
   }
   // Clean up memory
   delete root->left->left;
   delete root->left->right;
   delete root->right->left;
   delete root->right->right;
   delete root->left;
   delete root->right;
   delete root;
   return 0;
}

Output

The tree is NOT an Even-Odd Tree.

Time Complexity − O(N), N is the number of nodes in the binary tree.

Space Complexity − O(w), w is the number of nodes in a level with maximum nodes.

Conclusion

In conclusion, in order to determine if a binary tree is an even-odd tree or not, we can perform two types of traversals, that is, Depth First Search and Breadth First Search each having the same time complexities.

Updated on: 25-Oct-2023

85 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements