Home > Software design >  Checking if a binary tree is perfect in C
Checking if a binary tree is perfect in C

Time:11-17

I am writing a function to check whether a tree is a perfect binary tree and here is my code:

#include "binary_trees.h"

/**
 * binary_tree_is_perfect - checks if a binary tree is perfect
 * @tree: is a pointer to the root node of the tree to check
 *
 * Return: If the tree is perfect, it returns 1. Otherwise, it
 * returns 0.
 */
int binary_tree_is_perfect(const binary_tree_t *tree)
{
    int check, depth, level;

    if (tree == NULL)
        return (0);
    level = 0;
    depth  = find_depth_left(tree);
    check = isPerfect(tree, depth, level);
    return (check); 
}

/**
 * find_depth_left - finds the depth of the left most leaf
 * in a binary tree
 * @tree: is a pointer to the tree to measure the left most
 * depth
 *
 * Return: The depth of the left most node
 */
int find_depth_left(const binary_tree_t *tree)
{
    if (!tree->left)
        return (0);
    return (1   find_depth_left(tree->left));
}

/**
 * isPerfect - helper function to find if a binary tree is perfect
 * @depth: this is the left most depth of the tree
 * @level: this is the level where to the check is happening
 *
 * Return: If the tree is perfect, it returns 1. Otherwise, it
 * returns 0.
 */
int isPerfect(const binary_tree_t *tree, int depth, int level)
{
    if (!tree->left && !tree->right)
        return (depth == (level   1));  
    if (!tree->left || !tree->right)
        return (0);
    return (isPerfect(tree->left, depth, level   1) &&
            isPerfect(tree->right, depth, level   1));
}

My logic: I will find the left most leaf node of the tree (this is just my choice), then I will check whether the nodes will have two children or none with isPerfect function. But for every tree I input, I get 0 (meaning the tree is not perfect). This happens even if the tree is a perfect binary tree. Where did my logic go wrong?

CodePudding user response:

First the code was well thought out.

The internal (recursive) functions work on a non-null node. That would be fine for a OOP, object oriented programming, language, as then the function could be a member function on the node class binary_tree_t.

However here it led to difficulty: find_depth on a single node tree would logically be 1, not 0.

You could write it with accepting tree parameters as null. Then level and depth coincide.

bool binary_tree_is_perfect(const binary_tree_t *tree)
{
    int depth  = find_depth_left(tree);
    int level = 0;
    bool check = isPerfect(tree, depth, level);
    return check; 
}

int find_depth_left(const binary_tree_t *tree)
{
    if (!tree)
        return 0;
    return 1   find_depth_left(tree->left);
}

bool isPerfect(const binary_tree_t *tree, int depth, int level)
{
    if (!tree)
        return level == depth;
    if (!tree->left != !tree->right)
        return false;
    return isPerfect(tree->left, depth, level) &&
           isPerfect(tree->right, depth, level);
}

So it was a semantic (=in meanding) difference between level and depth. For the logic it would have been better to use one variable: expectedDepth.

bool binary_tree_is_perfect(const binary_tree_t *tree)
{
    int expectedDepth  = find_depth_left(tree);
    bool check = isPerfect(tree, expectedDepth);
    return check; 
}

int find_depth_left(const binary_tree_t *tree)
{
    return !tree ? 0 : 1   find_depth_left(tree->left);
}

bool isPerfect(const binary_tree_t *tree, int expectedDepth)
{
    if (!tree)
        return 0 == expectedDepth;
    if (!tree->left != !tree->right)
        return false;
    return expectedDepth >= 0 &&
           isPerfect(tree->left, exoectedDepth - 1l) &&
           isPerfect(tree->right, expectedDepth - 1);
}

expectedDepth >= 0 && is probably not needed as you took the expected depth from the left most leaf, as then the left subtree's isPerfect will return false. Interesting is it not?

  • Related