Reputation: 31
I'm new to C; I just made this function which counts the leaves in a given BST: is it correct? I've tried some test cases and they worked but I wanted to confirm it. I was also wondering if this is good coding. It's a very different method from ones I've seen online so I was wondering if I'm potentially doing something that's bad practice.
int Leaves(node *root) {
static int aa = 0;
node *b = root;
if (root != NULL) {
Leaves(root->left_child);
Leaves(root->right_child);
if (root->left_child == NULL && root->right_child == NULL) {
aa++;
}
}
if (root == b) { // only returns when I have gone all the way to the
// beginning of the call stack (the root)
return aa;
}
}
Upvotes: 1
Views: 341
Reputation: 753805
The static
variable aa
means the function cannot usefully be called twice in a single execution because there's no way to set it back to zero. That alone means your code is wrong. Static variables in recursive functions are almost always a signal of trouble.
There are also multiple paths through the function that do not return a value. You make multiple recursive calls to the function but ignore the returned value. Both those also mean the code is wrong.
I think this code does the job. The 'not a real node' case is relevant (executed) when one child is null and the other is not.
int numberOfLeaves(Node *N)
{
if (N == NULL)
return 0; /* This isn't a real node */
if (N->left_child == NULL && N->right_child == NULL)
return 1; /* This is a leaf node */
return numberOfLeaves(N->left_child) +
numberOfLeaves(N->right_child);
}
Untested code — and there isn't a framework for an MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example) — the same idea by a different name. That makes it unduly hard to test.
Here is a test program, based on the code I developed for an answer for SO 5495-1700. There, too, the question did not include an MCVE. The node type has pointers left
and right
rather than left_child
and right_child
as in this question. The function in the question has been renamed too.
/* SO 7400-0791 - recursive function numberOfLeaves() */
/* Adapted from code for SO 5495-1700 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node Node;
struct Node
{
int data;
Node *left;
Node *right;
};
static Node *createNode(int value);
static void freeSubtree(Node *node);
static Node *insertNode(Node *root, int value);
static int numberOfLeaves(Node *N);
int numberOfLeaves(Node *N)
{
if (N == NULL)
return 0; /* This isn't a real node */
if (N->left == NULL && N->right == NULL)
return 1; /* This is a leaf node */
return numberOfLeaves(N->left) + numberOfLeaves(N->right);
}
Node *insertNode(Node *root, int value)
{
if (root == NULL)
root = createNode(value);
else if (value < root->data)
root->left = insertNode(root->left, value);
else if (value > root->data)
root->right = insertNode(root->right, value);
return root;
}
void freeSubtree(Node *N)
{
if (N == NULL)
return;
freeSubtree(N->right);
freeSubtree(N->left);
N->right = NULL;
N->left = NULL;
free(N);
}
Node *createNode(int value)
{
Node *newNode = (Node *) malloc(sizeof(Node));
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
static void printValueIndented(int level, int value)
{
for (int i = 0; i < level; i++)
fputs(" ", stdout);
printf("%d\n", value);
}
static void printTree(const char *tag, Node *root, int level)
{
if (root == NULL)
return;
if (level == 0 && tag != NULL)
printf("%s\n", tag);
printValueIndented(level, root->data);
printTree(tag, root->left, level + 1);
printTree(tag, root->right, level + 1);
}
int main(void)
{
Node *root = 0;
printf("Sequence:\n");
for (int i = 0; i < 20; i++)
{
int value = i;
root = insertNode(root, i);
printf("%2d: Inserted %2d - Number of leaf nodes: %d\n",
i, value, numberOfLeaves(root));
}
printTree("Sequence", root, 0);
freeSubtree(root);
printf("Random:\n");
srand(time(0));
root = 0;
for (int i = 0; i < 20; i++)
{
int value = rand() % 53;
root = insertNode(root, value);
printf("%2d: Inserted %2d - Number of leaf nodes: %d\n",
i, value, numberOfLeaves(root));
}
printTree("Random", root, 0);
freeSubtree(root);
printf("Computed:\n");
root = 0;
for (int i = 0; i < 20; i++)
{
int value = (13 * i + 7) % 47;
root = insertNode(root, value);
printf("%2d: Inserted %2d - Number of leaf nodes: %d\n",
i, value, numberOfLeaves(root));
}
printTree("Computed", root, 0);
freeSubtree(root);
return 0;
}
Output:
Sequence:
0: Inserted 0 - Number of leaf nodes: 1
1: Inserted 1 - Number of leaf nodes: 1
2: Inserted 2 - Number of leaf nodes: 1
3: Inserted 3 - Number of leaf nodes: 1
4: Inserted 4 - Number of leaf nodes: 1
5: Inserted 5 - Number of leaf nodes: 1
6: Inserted 6 - Number of leaf nodes: 1
7: Inserted 7 - Number of leaf nodes: 1
8: Inserted 8 - Number of leaf nodes: 1
9: Inserted 9 - Number of leaf nodes: 1
10: Inserted 10 - Number of leaf nodes: 1
11: Inserted 11 - Number of leaf nodes: 1
12: Inserted 12 - Number of leaf nodes: 1
13: Inserted 13 - Number of leaf nodes: 1
14: Inserted 14 - Number of leaf nodes: 1
15: Inserted 15 - Number of leaf nodes: 1
16: Inserted 16 - Number of leaf nodes: 1
17: Inserted 17 - Number of leaf nodes: 1
18: Inserted 18 - Number of leaf nodes: 1
19: Inserted 19 - Number of leaf nodes: 1
Sequence
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Random:
0: Inserted 13 - Number of leaf nodes: 1
1: Inserted 28 - Number of leaf nodes: 1
2: Inserted 7 - Number of leaf nodes: 2
3: Inserted 44 - Number of leaf nodes: 2
4: Inserted 41 - Number of leaf nodes: 2
5: Inserted 39 - Number of leaf nodes: 2
6: Inserted 29 - Number of leaf nodes: 2
7: Inserted 45 - Number of leaf nodes: 3
8: Inserted 7 - Number of leaf nodes: 3
9: Inserted 12 - Number of leaf nodes: 3
10: Inserted 42 - Number of leaf nodes: 4
11: Inserted 27 - Number of leaf nodes: 5
12: Inserted 52 - Number of leaf nodes: 5
13: Inserted 11 - Number of leaf nodes: 5
14: Inserted 36 - Number of leaf nodes: 5
15: Inserted 22 - Number of leaf nodes: 5
16: Inserted 44 - Number of leaf nodes: 5
17: Inserted 23 - Number of leaf nodes: 5
18: Inserted 26 - Number of leaf nodes: 5
19: Inserted 47 - Number of leaf nodes: 5
Random
13
7
12
11
28
27
22
23
26
44
41
39
29
36
42
45
52
47
Computed:
0: Inserted 7 - Number of leaf nodes: 1
1: Inserted 20 - Number of leaf nodes: 1
2: Inserted 33 - Number of leaf nodes: 1
3: Inserted 46 - Number of leaf nodes: 1
4: Inserted 12 - Number of leaf nodes: 2
5: Inserted 25 - Number of leaf nodes: 3
6: Inserted 38 - Number of leaf nodes: 3
7: Inserted 4 - Number of leaf nodes: 4
8: Inserted 17 - Number of leaf nodes: 4
9: Inserted 30 - Number of leaf nodes: 4
10: Inserted 43 - Number of leaf nodes: 4
11: Inserted 9 - Number of leaf nodes: 5
12: Inserted 22 - Number of leaf nodes: 6
13: Inserted 35 - Number of leaf nodes: 7
14: Inserted 1 - Number of leaf nodes: 7
15: Inserted 14 - Number of leaf nodes: 7
16: Inserted 27 - Number of leaf nodes: 7
17: Inserted 40 - Number of leaf nodes: 7
18: Inserted 6 - Number of leaf nodes: 8
19: Inserted 19 - Number of leaf nodes: 9
Computed
7
4
1
6
20
12
9
17
14
19
33
25
22
30
27
46
38
35
43
40
Upvotes: 4