如何清空 GLib 树?
How to empty a GLib Tree?
为了清空 GLib 树,必须首先遍历树并填充所有找到的键的列表。然后可以使用 g_tree_remove
函数清空树。问题是我不确定如何从遍历函数中填充列表。这是我试过的
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
//Prototypes
gint treeCompareFunction (const gchar* a, const gchar* b, gpointer self);
gboolean traverseTree(gpointer key, gpointer value, gpointer data);
int main()
{
GTree* tree = g_tree_new_full ((GCompareDataFunc) treeCompareFunction, NULL, NULL, NULL);
// Insert data into the tree
g_tree_insert (tree, "key 1", "val 1");
g_tree_insert (tree, "key 2", "val 2");
g_tree_insert (tree, "key 3", "val 3");
GSList* list = NULL;
// Try to get all the keys of the tree in a list
g_tree_foreach (tree, (GTraverseFunc)traverseTree, list);
printf ("List size after tree traversal: %" G_GUINT32_FORMAT "\n", g_slist_length(list));
//TODO empty the tree
return 0;
}
gint treeCompareFunction (const gchar* a, const gchar* b, gpointer self) {
return g_strcmp0(a, b);
}
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
data = g_slist_append(data, key);
printf ("List size in traversal function: %" G_GUINT32_FORMAT "\n", g_slist_length(data));
return FALSE;
}
输出为
List size in traversal function: 1
List size in traversal function: 1
List size in traversal function: 1
List size after tree traversal: 0
我将如何获取列表中的所有键然后清空树?
你需要传递一个指向你的GSList*
的指针,而不是GSList*
本身,否则遍历函数修改的是指向列表头部的局部指针,而不是指向头部的指针main()
.
中的列表
GSList *list = NULL;
g_tree_foreach (tree, (GTraverseFunc)traverseTree, &list);
…
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
GSList *out_list = data;
*out_list = g_slist_append(*out_list, key);
printf ("List size in traversal function: %" G_GUINT32_FORMAT "\n", g_slist_length(*out_list));
return FALSE;
}
另外,请注意,使用 g_slist_append()
迭代地附加到链表将为您提供 O(N^2) 性能,而 g_slist_length()
需要 O(N) 时间。使用指针数组总体上会更容易和更有效:
GPtrArray *items_to_remove = g_ptr_array_sized_new (g_tree_nnodes (tree));
g_tree_foreach (tree, (GTraverseFunc)traverseTree, items_to_remove);
…
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
GPtrArray *items_to_remove = data;
g_ptr_array_add(items_to_remove, key);
printf ("List size in traversal function: %u\n", items_to_remove->len);
return FALSE;
}
为了清空 GLib 树,必须首先遍历树并填充所有找到的键的列表。然后可以使用 g_tree_remove
函数清空树。问题是我不确定如何从遍历函数中填充列表。这是我试过的
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
//Prototypes
gint treeCompareFunction (const gchar* a, const gchar* b, gpointer self);
gboolean traverseTree(gpointer key, gpointer value, gpointer data);
int main()
{
GTree* tree = g_tree_new_full ((GCompareDataFunc) treeCompareFunction, NULL, NULL, NULL);
// Insert data into the tree
g_tree_insert (tree, "key 1", "val 1");
g_tree_insert (tree, "key 2", "val 2");
g_tree_insert (tree, "key 3", "val 3");
GSList* list = NULL;
// Try to get all the keys of the tree in a list
g_tree_foreach (tree, (GTraverseFunc)traverseTree, list);
printf ("List size after tree traversal: %" G_GUINT32_FORMAT "\n", g_slist_length(list));
//TODO empty the tree
return 0;
}
gint treeCompareFunction (const gchar* a, const gchar* b, gpointer self) {
return g_strcmp0(a, b);
}
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
data = g_slist_append(data, key);
printf ("List size in traversal function: %" G_GUINT32_FORMAT "\n", g_slist_length(data));
return FALSE;
}
输出为
List size in traversal function: 1
List size in traversal function: 1
List size in traversal function: 1
List size after tree traversal: 0
我将如何获取列表中的所有键然后清空树?
你需要传递一个指向你的GSList*
的指针,而不是GSList*
本身,否则遍历函数修改的是指向列表头部的局部指针,而不是指向头部的指针main()
.
GSList *list = NULL;
g_tree_foreach (tree, (GTraverseFunc)traverseTree, &list);
…
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
GSList *out_list = data;
*out_list = g_slist_append(*out_list, key);
printf ("List size in traversal function: %" G_GUINT32_FORMAT "\n", g_slist_length(*out_list));
return FALSE;
}
另外,请注意,使用 g_slist_append()
迭代地附加到链表将为您提供 O(N^2) 性能,而 g_slist_length()
需要 O(N) 时间。使用指针数组总体上会更容易和更有效:
GPtrArray *items_to_remove = g_ptr_array_sized_new (g_tree_nnodes (tree));
g_tree_foreach (tree, (GTraverseFunc)traverseTree, items_to_remove);
…
gboolean traverseTree(gpointer key, gpointer value, gpointer data) {
GPtrArray *items_to_remove = data;
g_ptr_array_add(items_to_remove, key);
printf ("List size in traversal function: %u\n", items_to_remove->len);
return FALSE;
}