简体   繁体   English

计算给定二叉树中的叶子

[英]Count the leaves in a given Binary Tree

I'm new to C;我是 C 的新用户; I just made this function which counts the leaves in a given BST: is it correct?我刚刚制作了这个 function 来计算给定 BST 中的叶子:它是正确的吗? 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;
  }
}

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. static变量aa意味着 function 不能在单次执行中有效地调用两次,因为无法将其设置回零。 That alone means your code is wrong.仅此一项就意味着您的代码是错误的。 Static variables in recursive functions are almost always a signal of trouble. Static 递归函数中的变量几乎总是出问题的信号。

There are also multiple paths through the function that do not return a value.也有多个路径通过 function 不返回值。 You make multiple recursive calls to the function but ignore the returned value.您对 function 进行多次递归调用,但忽略返回值。 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.当一个孩子是 null 而另一个不是时,“不是真实节点”的情况是相关的(执行)。

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.未经测试的代码——并且没有用于 MCVE(最小、完整、可验证的示例——或 MRE 或 SO 现在使用的任何名称)或 SSCCE(简短、独立、正确的示例)的框架——不同的相同想法名称。 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 .这是一个测试程序,基于我为SO 5495-1700的答案开发的代码。 There, too, the question did not include an MCVE.那里的问题也不包括 MCVE。 The node type has pointers left and right rather than left_child and right_child as in this question.节点类型有指针leftright而不是这个问题中的left_childright_child The function in the question has been renamed too.问题中的 function 也已重命名。

/* 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: 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM