计算任何树时间改进的节点

时间:2016-05-10 15:19:51

标签: 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;
    }
    if (HT == NULL)
    {
        return;
    }
    else 
    {
        number++;
        for (int i = 0;i < HT->nr_of_sons;i++)
        {
            numbering(HT->next[i], 0);
        }
    }
}

有没有办法改进此功能,以加快速度? 编辑:我使用此功能的方式是:

int main()
{
//create tree;
 numbering(tree,0);
 numbering(tree,1);
}

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

2 个答案:

答案 0 :(得分:2)

你有一个非常奇怪的递归函数 - 你在函数中使用一个永远不会重置的静态变量,所以每个程序运行只能使用一次函数!

我会这样重写:

undo_rocketloader = function() {
        // If CloudFlare is active attempt to undo the damage to document functions
        if (window.CloudFlare) {
            var i, hp = HTMLDocument.prototype;
            for (i in hp) {
                // Using try to avoid "illegal invocation" errors
                try {
                    // Make sure document functions are same as HTMLDocument.prototype functions
                    if (typeof hp[i] == 'function' && document[i] != hp[i])
                        document[i] = hp[i];
                } catch (e) {}
            }
            // TODO: Retrieve window.getComputedStyle
            // Following method failed because Window.prototype.getComputedStyle is undefined.
            // I couldn't find getComputedStyle in any prototype :(
            // if (window.getComputedStyle != XXX.getComputedStyle)
            //  window.getComputedStyle = XXX.getComputedStyle;             
        } else {
            // If CloudFlare was not loaded yet - this will prevent it from loading
            CloudFlare = {
                define: function() {}
            };
        }
        var damagedScripts = document.querySelectorAll('script[type="text/rocketscript"]');
        for (i = 0; i < damagedScripts.length; i++) {
            // If `type` is removed before changing the src, the script would run.
            // We rely on the `data-rocketoptimized` to tell if the script was already called or not (see rocket-loader code near "Scanning for scripts")
            if (damagedScripts[i].getAttribute('data-rocketoptimized') != "true") {
                // script has not run yet? remove type, so that the src change will cause this script to run
                damagedScripts[i].removeAttribute('type'); // 'text/javascript' is default when `type` is removed
            }
            damagedScripts[i].setAttribute('data-rocketoptimized', 'true'); // make sure to never run it again
            if (damagedScripts[i].hasAttribute('data-rocketsrc'))
                damagedScripts[i].setAttribute('src', damagedScripts[i].getAttribute('data-rocketsrc')) // when selecting a script we look for it's src attribute, not data-rocketsrc
            damagedScripts[i].removeAttribute('type'); // 'text/javascript' is default when `type` is removed
        }
    } //undo_rocketloader

如果您真的想要加快速度,可以通过添加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; } 字段来扩充节点结构,无论何时插入或删除节点,都会保留该字段。另一个想法是直接将指针到子阵列压缩到节点结构中:

size_t subtree_count

我在这里做的是使typedef struct node{ char item; int number_of_sons; node_t *sons[0]; } node_t; 变量是一个数组,而不是一个指向数组的指针。但它的大小为零(如果您的编译器需要,则使用sons[]),因为您不知道编译时的子数。但您可以简单地分配具有适当空间的节点:

[1]

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

答案 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;
}

我删除了你的ok变量并将返回值从void更改为int。

  1. 在案例库中,您返回0;
  2. 对于叶子,他们将返回1;
  3. 对于内部节点,它们将返回1 +中的节点数 子树。