【问题标题】:GTree from Glib example来自 Glib 示例的 GTree
【发布时间】:2020-04-15 21:52:49
【问题描述】:

所以我有一个这样的结构:

typedef struct sales
{
    int* salesN;
    int* salesP;
}*Sales;

我会有很多字符串,比如我想关联到这个结构的 char* 产品。就效率而言,来自 Glib 的 struct GTree 似乎是一个不错的选择。

基本上我希望键是字符串,值是结构。我还希望它们按字母顺序排序,所以我猜测比较函数应该是类似 strcmp 的东西。

但我无法启动和初始化 GTree。如果有人能给我一个关于如何初始化、如何插入以及如何搜索和修改某些值的快速代码示例,我将不胜感激。

非常感谢您。

【问题讨论】:

    标签: c data-structures glib


    【解决方案1】:

    首先,我们需要修复您的结构声明。这是typedef <type declaration> <name>。所以不是*Sales,而是Sales

    typedef struct sales
    {
        int* salesN;
        int* salesP;
    } Sales;
    

    现在我们按照the GTree documentation 中的说明,首先制作一棵树并告诉它如何比较键。

    GTree *sales_tree = g_tree_new(g_str_equal);
    

    我们不能使用strcmp,因为它的签名错误。相反,我们使用Hash Tables 中的函数。

    现在我们进行销售并使用密钥插入它。这一切都是通过指针、键和值来完成的。

    // Make a Sale
    int n = 23;
    int p = 42;
    Sales sale = { .salesN = &n, .salesP = &p };
    
    // Insert it as "The Stuff".
    const char *key = "The Stuff";
    g_tree_insert(sales_tree, &key, &sale);
    

    我们可以使用相同的键将其作为指针检索。

    Sales *found = g_tree_lookup(sales_tree, key);
    printf("n %d, p %d\n", *found->salesN, *found->salesP);
    

    最后,清理树以避免内存泄漏。

    g_tree_destroy(sales_tree);
    

    g_tree_foreach 的工作方式与q_sort_r 非常相似。它需要一个GTraverseFunc 类型的函数指针,它将在每个节点上调用。如果返回 true,则遍历停止。

    g_tree_foreach 接受一个额外的参数,该参数将传递给函数的每次调用。这允许您在遍历期间存储信息,而无需使用全局变量。

    例如,这里有一个小函数,它使用GPtrArray 来收集树中所有值的列表。

    gboolean find_all_nodes(gpointer key, gpointer value, gpointer all) {
        g_ptr_array_add(all, value);
        return FALSE;
    }
    

    然后我们像这样使用我们的函数遍历树。

    GPtrArray *all = g_ptr_array_new();
    g_tree_foreach(sales_tree, find_all_nodes, all);
    

    我们可以查看我们在指针数组中捕获的内容,确保在完成后释放它。

        for( int i = 0; i < all->len; i++ ) {
            Sales *s = g_ptr_array_index(all, i);
            printf("n %d, p %d\n", *s->salesN, *s->salesP);
        }
        g_ptr_array_free(all, TRUE);
    

    【讨论】:

    • 非常感谢。还有一件事。我不太了解 GTree 文档的 foreach 函数。 void g_tree_foreach (GTree *tree, GTraverseFunc func, gpointer user_data);假设我希望遍历树以总结每种产品的所有销售额。我不明白第二个和第三个参数应该是什么
    • @J.Gomes 与qsort_r 非常相似。 tree 是树。 func 是签名为GTraverseFunc 的函数指针。 user_data 是您选择的额外数据。 func 将在每个节点上使用其键、值和您的 user_data 调用。如果它返回 true,则遍历停止。您可以使用user_data 收集节点。我将添加一个示例。
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 2018-04-09
    • 2013-06-19
    相关资源
    最近更新 更多