GLIB容器 链表 双向链表 HASH表 TREE 的使用

安装备忘:

由于服务器上的python是2.4.2,而最新的 glib 2.34 需要 python2.5,简便起见,选择了glib-2.26.1.tar.gz 安装。

安装之前,如果gettext版本较低,要升级到0.17

代码编译

示例文件为glib.c

export PKG_CONFIG_PATH=/usr/local/glib-2.26.1/lib/pkgconfig/:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/usr/local/glib-2.26.1/lib/:$LD_LIBRARY_PATH

gcc glib.c -Wall `pkg-config --libs --cflags glib-2.0`

接口参考文献:

http://developer.gnome.org/glib/2.26/

针对hashtable系统提供了一些便捷方法:

/* Hash Functions
 */
gboolean g_str_equal (gconstpointer  v1,
                      gconstpointer  v2);
guint    g_str_hash  (gconstpointer  v);

gboolean g_int_equal (gconstpointer  v1,
                      gconstpointer  v2);
guint    g_int_hash  (gconstpointer  v);

gboolean g_int64_equal (gconstpointer  v1,
                        gconstpointer  v2);
guint    g_int64_hash  (gconstpointer  v);

gboolean g_double_equal (gconstpointer  v1,
                         gconstpointer  v2);
guint    g_double_hash  (gconstpointer  v);



下面是文件内容,依次尝试了不同容器的各种方法:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "glib.h"

void show_tree(const gchar* fname) {
	int i;
	int indent;
	int length = strlen(fname);

	for (i = 0; i < length; i++) {
		g_print("%c", fname[i]);
	}
	g_print("\n");

	for (i = 0, indent = 0; i < length; i++) {
		if(fname[i] != G_DIR_SEPARATOR)
			g_print("%c", fname[i]);
		else {
			indent++;
			switch(indent) {
				case 1 : g_print("the dir "); break;
				case 2 : g_print(" contains "); break;
				default : g_print(", which contains ");
			}
		}
	}
	g_print("\n");
}

gint item_compare(gconstpointer v1, gconstpointer v2) {
	return -strcmp((char *)v1, (char *)v2);
}

void item_visit(gpointer listdata, gpointer userdata) {
	g_print("%s -> %s\n", (char *)userdata, (char *)listdata);
}

void test_list() {
	GSList *mylist = NULL;

	mylist = g_slist_append(mylist, "alex");
	mylist = g_slist_append(mylist, "billy");
	mylist = g_slist_append(mylist, "coco");

	mylist = g_slist_prepend(mylist, "3");
	mylist = g_slist_prepend(mylist, "2");
	mylist = g_slist_prepend(mylist, "1");

	mylist = g_slist_insert(mylist, "insert", 1);

	GSList *item;
	for(item = mylist; item != NULL; item = g_slist_next(item)) {
		g_print("mylist -> %s\n", (gchar *)(item->data));
	}

	mylist = g_slist_sort(mylist, (GCompareFunc)item_compare);
	g_slist_foreach(mylist, (GFunc)item_visit, "mylist item");

	g_print("mylist header is : %s\n", (char *)mylist->data);

	g_slist_free(mylist);
}

typedef struct person {
	char *surname;
	char *name;
} person;

gint compare_item(gpointer v1, gpointer v2) {
	person *p1 = (person *)v1;
	person *p2 = (person *)v2;
	char n1[100] = {'\0'};
	char n2[100] = {'\0'};
	sprintf(n1, "%s%s", p1->surname, p1->name);
	sprintf(n2, "%s%s", p2->surname, p2->name);
	return strcmp(n1, n2);
}

gint traverse_tree(gpointer key, gpointer value, gpointer data) {
	person *p = (person *)key;
	g_print("[%s]%s:%s => %s\n", (char *)data, p->surname, p->name, (char *)value);
	return FALSE;
}

void test_tree() {
	GTree *mytree;
	mytree = g_tree_new((GCompareFunc)compare_item);

	person p1;
	p1.surname = strdup("zhou");
	p1.name = strdup("yu");
	g_tree_insert(mytree, &p1, "ubuntu");

	person p2;
	p2.surname = strdup("zhou");
	p2.name = strdup("runfa");
	g_tree_insert(mytree, &p2, "window");

	person p3;
	p3.surname = strdup("zhang");
	p3.name = strdup("guorong");
	g_tree_insert(mytree, &p3, "redhat");

	g_tree_traverse(mytree, traverse_tree, G_IN_ORDER, "in");
	g_tree_traverse(mytree, traverse_tree, G_PRE_ORDER, "pre");
	g_tree_traverse(mytree, traverse_tree, G_POST_ORDER, "post");

	person ps;
	ps.surname = strdup("zhang");
	ps.name = strdup("guorong");
	char *psvalue = (char *)g_tree_lookup(mytree, &ps);
	g_print("lookup p[%s:%s] -> %s\n", ps.surname, ps.name, psvalue);

    /**
	gpointer orig_key;
	gpointer orig_value;
	g_tree_lookup_extended(mytree, &ps, &orig_key, &orig_value);
	person *po = (person *)orig_key;
	char *vo = (char *)orig_value;
	g_print("lookup_extended p[%s:%s] -> %s\n", po->surname, po->name, vo);
	//po == &p3 [zhang:guorong]
	//free(p3.surname);
	//free(p3.name);
	free(po->surname);
	free(po->name);
	*/

	free(p1.surname);
	free(p1.name);
	free(p2.surname);
	free(p2.name);
	free(p3.surname);
	free(p3.name);
	free(ps.surname);
	free(ps.name);

	g_tree_destroy(mytree);
}

guint hash_code(gconstpointer key) {
    char *k = (char *)key;
    guint h;
    int i, len;
    for(i = 0, len = strlen(k); i < len; i++) {
        h = 31 * h + k[i];
    }
    printf("[hash_code] %s -> %d\n", k, h);
    return h;
}

gboolean hash_equal(gconstpointer key1, gconstpointer key2) {
    char *k1 = (char *)key1;
    char *k2 = (char *)key2;
    printf("[hash_equal] %s -> %s\n", k1, k2);
    return strcmp(k1, k2) == 0 ? TRUE : FALSE;
}

void key_destroy(gpointer data) {
    //do nothing
    printf("[key_destroy] : %s\n", (char *)data);
}

void value_destroy(gpointer data) {
    person *p = (person *)data;
    printf("[value_destroy] : %s %s\n", p->surname, p->name);
	free(p->surname);
	free(p->name);
}

void test_hashtable() {

	GHashTable *mytree;

	//mytree = g_hash_table_new_full((GHashFunc)hash_code, (GEqualFunc)hash_equal, (GDestroyNotify)key_destroy, (GDestroyNotify)value_destroy);
	//mytree = g_hash_table_new((GHashFunc)hash_code, (GEqualFunc)hash_equal);
        //this is convenience provided by ghash.h
        mytree = g_hash_table_new_full((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal, (GDestroyNotify)key_destroy, (GDestroyNotify)value_destroy);
	person p1;
	p1.surname = strdup("zhou");
	p1.name = strdup("yu");
    g_hash_table_insert(mytree, "ubuntu", &p1);

	person p2;
	p2.surname = strdup("zhou");
	p2.name = strdup("runfa");
	g_hash_table_insert(mytree, "window", &p2);

	person p3;
	p3.surname = strdup("zhang");
	p3.name = strdup("guorong");
	g_hash_table_insert(mytree, "redhat", &p3);

	person *ps = (person *)g_hash_table_lookup(mytree, "window");
	g_print("lookup -> %s : %s\n", ps->surname, ps->name);

    g_hash_table_destroy(mytree);
}

gint main(gint argc, gchar *argv[]) {

	show_tree("/usr/local/test.txt");

	test_list();

	test_tree();

	test_hashtable();

	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值