Во-первых, нам нужно исправить объявление структуры. Это typedef <type declaration> <name>
. Так что не *Sales
, а просто Sales
.
typedef struct sales
{
int* salesN;
int* salesP;
} Sales;
Теперь мы следуем инструкциям документации GTree , сначала мы создаем дерево и сообщаем ему, как сравнивать ключи.
GTree *sales_tree = g_tree_new(g_str_equal);
Мы не можем использовать strcmp
, потому что у него неправильная подпись. Вместо этого мы используем функции, найденные в Ха sh Таблицах .
Теперь мы делаем продажу и вставляем ее с ключом. Все это делается с помощью указателей, ключей и значений.
// 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);