Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 计算任意树时间改进的节点数_C_Tree - Fatal编程技术网

C 计算任意树时间改进的节点数

C 计算任意树时间改进的节点数,c,tree,C,Tree,我必须做一个计算我的树有多少元素的函数。我的树不是二叉树,是最普通的一种树 该节点是: typedef struct node{ char item; int number_of_sons; node **sons; } 我的计数功能是 void numbering(node *HT,int ok=0) { static int number = 0; if (ok == 1) { printf("%d", number); return

我必须做一个计算我的树有多少元素的函数。我的树不是二叉树,是最普通的一种树

该节点是:

typedef struct node{
char item;
int number_of_sons;
node **sons;
}
我的计数功能是

void numbering(node *HT,int ok=0)
{
    static int number = 0;
    if (ok == 1)
    {
        printf("%d", number);
        return;
    }
    if (HT == NULL)
    {
        return;
    }
    else 
    {
        number++;
        for (int i = 0;i < HT->nr_of_sons;i++)
        {
            numbering(HT->next[i], 0);
        }
    }
}

当我第二次调用该函数时,它会打印我的结果

也许这样更好、更有效:

int numbering(node *HT)
{
    if (!HT)
    {
        return 0;
    }

    int num = 1;
    for (int i = 0;i < HT->nr_of_sons;i++)
    {
        num += numbering(HT->next[i]);
    }
    return num;
}
int编号(节点*HT)
{
如果(!HT)
{
返回0;
}
int num=1;
对于(inti=0;inr\u的子;i++)
{
num+=编号(HT->next[i]);
}
返回num;
}
我删除了ok变量,并将返回值从void更改为int

  • 在案例库中,返回0
  • 对于叶子,他们将返回1
  • 对于内部节点,它们将返回1+中的节点数 子树

  • 也许这样更好、更高效:

    int numbering(node *HT)
    {
        if (!HT)
        {
            return 0;
        }
    
        int num = 1;
        for (int i = 0;i < HT->nr_of_sons;i++)
        {
            num += numbering(HT->next[i]);
        }
        return num;
    }
    
    int编号(节点*HT)
    {
    如果(!HT)
    {
    返回0;
    }
    int num=1;
    对于(inti=0;inr\u的子;i++)
    {
    num+=编号(HT->next[i]);
    }
    返回num;
    }
    
    我删除了ok变量,并将返回值从void更改为int

  • 在案例库中,返回0
  • 对于叶子,他们将返回1
  • 对于内部节点,它们将返回1+中的节点数 子树

  • 这里有一个非常奇怪的递归函数——在函数中使用的是一个永远不会重置的静态变量,因此该函数在每次程序运行时只能使用一次

    我会这样重写:

    size_t nodecount(node *root)
    {
        size_t count = 0;
        if (root)
        {
            count++;
            for (int i = 0; i < root->nr_of_sons; i++)
            {
                count += nodecount(root->sons[i]);
            }
        }
        return count;
    }
    
    我在这里所做的是使
    sons
    变量是一个数组,而不是指向数组的指针。但是它的大小为零(注意,如果编译器需要,请使用
    []
    [1]
    ),因为您不知道编译时的子代数。但您可以简单地分配具有适当空间量的节点:

    node_t* tree = (node_t*)malloc(sizeof(node_t) + num_sons*sizeof(node_t*));
    

    这将指针间接指向减少了一层,这可能有助于提高性能。

    这里有一个非常奇怪的递归函数——在函数中使用的是一个永远不会重置的静态变量,因此该函数每次程序运行只能使用一次

    我会这样重写:

    size_t nodecount(node *root)
    {
        size_t count = 0;
        if (root)
        {
            count++;
            for (int i = 0; i < root->nr_of_sons; i++)
            {
                count += nodecount(root->sons[i]);
            }
        }
        return count;
    }
    
    我在这里所做的是使
    sons
    变量是一个数组,而不是指向数组的指针。但是它的大小为零(注意,如果编译器需要,请使用
    []
    [1]
    ),因为您不知道编译时的子代数。但您可以简单地分配具有适当空间量的节点:

    node_t* tree = (node_t*)malloc(sizeof(node_t) + num_sons*sizeof(node_t*));
    

    这将指针间接指向减少一层,这可能有助于提高性能。

    变量
    ok
    的用途是什么?它似乎总是零。Ok是一个隐式参数,它使函数得到了2次使用。当ok=0时,它计算我得到的节点数,当ok=1时,函数打印节点数。出于调试目的,
    ok
    似乎启用了一些跟踪代码。不相关(至少在实现索引循环之前),没有理由对
    number of_sons
    进行签名。它应该是无符号类型,理想情况下,由于其对象计数的性质,它应该是
    size\u t
    。你永远不会有-N个儿子,所以从一开始就不要允许它。你的意思是
    /
    ,对吗?
    ok
    变量的用途是什么?它似乎总是零。Ok是一个隐式参数,它使函数得到了2次使用。当ok=0时,它计算我得到的节点数,当ok=1时,函数打印节点数。出于调试目的,
    ok
    似乎启用了一些跟踪代码。不相关(至少在实现索引循环之前),没有理由对
    number of_sons
    进行签名。它应该是无符号类型,理想情况下,由于其对象计数的性质,它应该是
    size\u t
    。你永远不会有-N个儿子,所以从一开始就不要允许。你的意思是
    /
    ,对吧?我现在明白了。从来没有想过间接操作会对性能产生如此大的影响(我必须存储10K元素)。我现在明白了。从来都不知道间接操作会对性能产生如此大的影响(我必须存储10K元素)。