glib 树

原文地址: http://hi.baidu.com/study_together/blog/item/0ffc733c224211cf7c1e7138.html

编译:gcc -g -Wall -O0 fuck.c -o fuck `pkg-config --libs --cflags glib-2.0`

1

树的基本操作

这里是在树中可以执行的一些基本操作:

 
  
#include < glib.h >
#include
< stdio.h >

int main( int argc, char ** argv) {
GTree
* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
g_tree_insert(t,
" c " , " Chicago " );
printf(
" The tree height is %d because there's only one node\n " , g_tree_height(t));
g_tree_insert(t,
" b " , " Boston " );
g_tree_insert(t,
" d " , " Detroit " );
printf(
" Height is %d since c is root; b and d are children\n " , g_tree_height(t));
printf(
" There are %d nodes in the tree\n " , g_tree_nnodes(t));
g_tree_remove(t,
" d " );
printf(
" After remove(), there are %d nodes in the tree\n " , g_tree_nnodes(t));
g_tree_destroy(t);
return 0 ;
}

***** Output *****

The tree height is 1 because there's only one node
Height is 2 since c is root; b and d are children
There are 3 nodes in the tree
After remove(), there are 2 nodes in the tree

2

替换和提取

在前面的 GHashTable 部分已经看到了 replace 和 steal 函数名, 关于 GTree 的函数也是如此。

g_tree_replace 会同时替换一个 GTree 条目的键和值,不同于 g_tree_insert,如果要插入的键是重复的,则它只是将值替换。

不需要调用任何 GDestroyNotify 函数,g_tree_steal 就可以删除一个节点。 这里是一个示例:

 
  
#include < glib.h >
#include
< stdio.h >

void key_d(gpointer data) {
printf(
" Key %s destroyed\n " , data);
}
void value_d(gpointer data) {
printf(
" Value %s destroyed\n " , data);
}
int main( int argc, char ** argv) {
GTree
* t = g_tree_new_full((GCompareDataFunc)g_ascii_strcasecmp,
NULL, (GDestroyNotify)key_d, (GDestroyNotify)value_d);
g_tree_insert(t,
" c " , " Chicago " );
g_tree_insert(t,
" b " , " Boston " );
g_tree_insert(t,
" d " , " Detroit " );
printf(
" >Replacing 'b', should get destroy callbacks\n " );
g_tree_replace(t,
" b " , " Billings " );
printf(
" >Stealing 'b', no destroy notifications will occur\n " );
g_tree_steal(t,
" b " );
printf(
" >Destroying entire tree now\n " );
g_tree_destroy(t);
return 0 ;
}

***** Output *****

>Replacing 'b', should get destroy callbacks
Value Boston destroyed
Key b destroyed
>Stealing 'b', no destroy notifications will occur
>Destroying entire tree now
Key d destroyed
Value Detroit destroyed
Key c destroyed
Value Chicago destroyed

3

查找数据

GTree 具备只查找键或者同时查找键和值的方法。这与在 GHashTable 部分中接触到的非常类似;

有一个 lookup 以及一个 lookup_extended。这里是一个示例:

 
  
#include < glib.h >
#include
< stdio.h >

int main( int argc, char ** argv) {
GTree
* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
g_tree_insert(t,
" c " , " Chicago " );
g_tree_insert(t,
" b " , " Boston " );
g_tree_insert(t,
" d " , " Detroit " );
printf(
" The data at 'b' is %s\n " , g_tree_lookup(t, " b " ));
printf(
" %s\n " , g_tree_lookup(t, " a " ) ? " My goodness! " : " As expected, couldn't find 'a' " );

gpointer
* key = NULL;
gpointer
* value = NULL;
g_tree_lookup_extended(t,
" c " , (gpointer * ) & key, (gpointer * ) & value);
printf(
" The data at '%s' is %s\n " , key, value);
gboolean found
= g_tree_lookup_extended(t, " a " , (gpointer * ) & key, (gpointer * ) & value);
printf(
" %s\n " , found ? " My goodness! " : " As expected, couldn't find 'a' " );

g_tree_destroy(t);
return 0 ;
}

***** Output *****

The data at 'b' is Boston
As expected, couldn't find 'a'
The data at 'c' is Chicago
As expected, couldn't find 'a'


4

使用 foreach 列出树

GTree 提供了一个 g_tree_foreach 函数,用来以有序的顺序遍历整棵对。这里是一个示例:

 
  
#include < glib.h >
#include
< stdio.h >

gboolean iter_all(gpointer key, gpointer value, gpointer data) {
printf(
" %s, %s\n " , key, value);
return FALSE;
}
gboolean iter_some(gpointer key, gpointer value, gpointer data) {
printf(
" %s, %s\n " , key, value);
return g_ascii_strcasecmp(key, " b " ) == 0 ;
}
int main( int argc, char ** argv) {
GTree
* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
g_tree_insert(t,
" d " , " Detroit " );
g_tree_insert(t,
" a " , " Atlanta " );
g_tree_insert(t,
" c " , " Chicago " );
g_tree_insert(t,
" b " , " Boston " );
printf(
" Iterating all nodes\n " );
g_tree_foreach(t, (GTraverseFunc)iter_all, NULL);
printf(
" Iterating some of the nodes\n " );
g_tree_foreach(t, (GTraverseFunc)iter_some, NULL);
g_tree_destroy(t);
return 0 ;
}

***** Output *****

Iterating all nodes
a, Atlanta
b, Boston
c, Chicago
d, Detroit
Iterating some of the nodes
a, Atlanta
b, Boston

5

搜索

可以使用 g_tree_foreach 搜索条目,如果知道键,可以使用 g_tree_lookup。 不过,要进行更复杂地搜索,可以使用 g_tree_search 函数。

这里是其工作方式:

 
  
#include < glib.h >
#include
< stdio.h >

gint finder(gpointer key, gpointer user_data) {
int len = strlen(( char * )key);
if (len == 3 ) {
return 0 ;
}
return (len < 3 ) ? 1 : - 1 ;
}
int main( int argc, char ** argv) {
GTree
* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
g_tree_insert(t,
" dddd " , " Detroit " );
g_tree_insert(t,
" a " , " Annandale " );
g_tree_insert(t,
" ccc " , " Cleveland " );
g_tree_insert(t,
" bb " , " Boston " );
gpointer value
= g_tree_search(t, (GCompareFunc)finder, NULL);
printf(
" Located value %s; its key is 3 characters long\n " , value);
g_tree_destroy(t);
return 0 ;
}

***** Output *****

Located value Cleveland; its key is 3 characters long

6

不只是二叉:n-叉 树

GLib n-叉 树实现基于 GNode 数据结构;以前所述,它允许每个父节点有多个子节点。 好像很少会用到它,不过,完整起见,这里给出一个用法示例:

 
  
#include < glib.h >
#include
< stdio.h >

gboolean iter(GNode
* n, gpointer data) {
printf(
" %s " , n -> data);
return FALSE;
}
int main( int argc, char ** argv) {
GNode
* root = g_node_new( " Atlanta " );
g_node_append(root, g_node_new(
" Detroit " ));
GNode
* portland = g_node_prepend(root, g_node_new( " Portland " ));
printf(
" >Some cities to start with\n " );
g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
- 1 , iter, NULL);
printf(
" \n>Inserting Coos Bay before Portland\n " );
g_node_insert_data_before(root, portland,
" Coos Bay " );
g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
- 1 , iter, NULL);
printf(
" \n>Reversing the child nodes\n " );
g_node_reverse_children(root);
g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
- 1 , iter, NULL);
printf(
" \n>Root node is %s\n " , g_node_get_root(portland) -> data);
printf(
" >Portland node index is %d\n " , g_node_child_index(root, " Portland " ));
g_node_destroy(root);
return 0 ;
}

***** Output *****

>Some cities to start with
Atlanta Portland Detroit
>Inserting Coos Bay before Portland
Atlanta Coos Bay Portland Detroit
>Reversing the child nodes
Atlanta Detroit Portland Coos Bay
>Root node is Atlanta
>Portland node index is 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值