【问题标题】:How can you clean an entire POSIX tree with only POSIX functions?你怎么能用 POSIX 函数清理整个 POSIX 树?
【发布时间】:2019-08-31 18:37:52
【问题描述】:

已经用tsearch 填充了一个 POSIX 二叉树,如何清理整个树? GCC 提供了tdestroy 作为扩展,但是如果你想使用 POSIX-only 函数怎么做呢?

我当前的实现使用twalk 遍历树,对于endorderleaf 节点,调用tdelete,但可以理解的是,这显示了关于const-correctness 的警告:

static void free_tree(const void *node, const VISIT which, const int depth)
{
        struct search_entry *entry;
        switch (which) {
                case endorder:
                case leaf:
                        entry = *(struct search_entry **)node;
                        tdelete(entry->key, &node, search_entry_compare);
                        free(entry);
        }
}

对于符合 POSIX 的应用程序的预期方法是什么?

【问题讨论】:

    标签: c posix


    【解决方案1】:

    tsearch() 系列函数的 POSIX 描述有一个信息丰富的示例部分,该部分显示标准如何认为您可以删除树的所有元素(作为更大、完整示例的一部分如何使用这些功能):

    /* Delete all nodes in the tree */
    while (root != NULL) {
        elementptr = *(struct element **)root;
        printf("deleting node: string = %s,  count = %d\n",
               elementptr->string,
               elementptr->count);
        tdelete((void *)elementptr, &root, delete_root);
        free(elementptr);
    }
    

    基本上,它会反复删除带有tdelete() 的根节点,直到不再有要删除的根节点为止。还显示了delete_root() 函数——它是一个空操作,成功返回 0。

    我们可以在致电tdelete() 时讨论演员的优点(或不足)。

    【讨论】:

    • 太糟糕了,Linux 程序员手册中没有这样的内容;从 4.16 开始,它所拥有的只是如何公开和使用 tdestroy
    • 是的,tdestroy3posix 手册页省略了这一点,这将非常有用。感谢您的回答!
    【解决方案2】:

    twalk()action 调用tdelete() 的建议解决方案与actioncompar 不更改树的应用程序的POSIX 要求相冲突。在实践中,可能会在免费或不完全清理后使用。

    我能想到的最好的办法是要么不使用 tsearch/tfind/tdelete/twalk,要么分配新内存来存储 twalk() 结果并在之后使用 tdelete()

    不使用 tsearch/tfind/tdelete/twalk 也可能允许在现代架构上比二叉树更有效的数据结构,例如基数尝试和哈希表。

    【讨论】:

    • 我不会避免使用 tsearch,因为“基数尝试和哈希表 [...] 在现代架构上往往更有效”,除非您确实遇到了要解决的性能问题并且您已经测量过它会有所作为。 tsearch API 非常易于使用,是最佳的 big-O,不依赖于键的类型(而 radix 是),并且倾向于使代码非常轻巧。
    猜你喜欢
    • 1970-01-01
    • 2016-01-11
    • 2012-02-18
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    相关资源
    最近更新 更多