首先贴出来glib库的帮助文档网址
http://web.mit.edu/barnowl/share/gtk-doc/html/glib/glib-Doubly-Linked-Lists.html#g-list-find
由于双向链表与单向链表的很多函数功能和名称都是一样的,这里对一些函数就不细说了,具体有什么不了解的可以通过上面给的网址了解。
函数先说一下双向链表的结构体
typedef struct { gpointer data; GList *next; GList *prev; } GList;
Doubly-Linked Lists — linked lists containing integer values or pointers to data, with the ability to iterate over the list in both directions。
这个是双向链表的官方描述,其中说的的数据可以是int型的值或者是指针类型,我觉得就是32为能够表示的就可以了,你愿意的话char型的也可以存储,就是浪费空间而已。
然后是他所支持的功能函数
#include <glib.h> GList; GList* g_list_append (GList *list, gpointer data); GList* g_list_prepend (GList *list, gpointer data); GList* g_list_insert (GList *list, gpointer data, gint position); GList* g_list_insert_before (GList *list, GList *sibling, gpointer data); GList* g_list_insert_sorted (GList *list, gpointer data, GCompareFunc func); GList* g_list_remove (GList *list, gconstpointer data); GList* g_list_remove_link (GList *list, GList *llink); GList* g_list_delete_link (GList *list, GList *link_); GList* g_list_remove_all (GList *list, gconstpointer data); void g_list_free (GList *list); GList* g_list_alloc (void); void g_list_free_1 (GList *list); #define g_list_free1 guint g_list_length (GList *list); GList* g_list_copy (GList *list); GList* g_list_reverse (GList *list); GList* g_list_sort (GList *list, GCompareFunc compare_func); gint (*GCompareFunc) (gconstpointer a, gconstpointer b); GList* g_list_insert_sorted_with_data (GList *list, gpointer data, GCompareDataFunc func, gpointer user_data); GList* g_list_sort_with_data (GList *list, GCompareDataFunc compare_func, gpointer user_data); gint (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data); GList* g_list_concat (GList *list1, GList *list2); void g_list_foreach (GList *list, GFunc func, gpointer user_data); void (*GFunc) (gpointer data, gpointer user_data); GList* g_list_first (GList *list); GList* g_list_last (GList *list); #define g_list_previous (list) #define g_list_next (list) GList* g_list_nth (GList *list, guint n); gpointer g_list_nth_data (GList *list, guint n); GList* g_list_nth_prev (GList *list, guint n); GList* g_list_find (GList *list, gconstpointer data); GList* g_list_find_custom (GList *list, gconstpointer data, GCompareFunc func); gint g_list_position (GList *list, GList *llink); gint g_list_index (GList *list, gconstpointer data); void g_list_push_allocator (gpointer allocator); void g_list_pop_allocator (void);
下面贴出例子程序,这里就不分开单独讲解,因为很多和单链表相似的地方
#include <stdio.h> #include <stdlib.h> #include <glib.h> //#include <glib/gprintf.h> static gint sort(gconstpointer p1, gconstpointer p2)//排序函数,正向排序 { gint32 a, b; a = GPOINTER_TO_INT(p1); b = GPOINTER_TO_INT(p2); return (a > b ? +1 : a == b ? 0 : -1); } static gint sort_r(gconstpointer p1, gconstpointer p2)//逆向排序 { gint32 a, b; a = GPOINTER_TO_INT(p1); b = GPOINTER_TO_INT(p2); return (a < b ? +1 : a == b ? 0 : -1); } static void print(gpointer p1, gpointer p2)//打印函数,只打印P1 { g_printf("%d,", *(gint*)p1); } static void test_list(void) { GList *list = NULL; gint nums[10] = {0,1,2,3,4,5,6,7,8,9}; // GList* g_list_append(GList *list, gpointer data);//尾加,和单链表是一样的功能 list = g_list_append(list, &nums[1]); g_printf("The first item should be '%d' now.\t\tResult: %d.\n", nums[1], *(gint*)list->data); // GList* g_list_prepend(GList *list, gpointer data);//头加 list = g_list_prepend(list, &nums[0]); // GList* g_list_first(GList *list);//获得头指针 g_printf("The first item should be '%d' now.\t\tResult: %d.\n", nums[0], *(gint*)g_list_first(list)->data); // GList* g_list_insert(GList *list, gpointer data, gint position);//在position位置插入data数据 list = g_list_insert(list, &nums[2], 2); // GList* g_list_last(GList *list); 返回链表最后一个的指针 g_printf("The last item should be '%d' now.\t\tResult: %d.\n", nums[2], *(gint*)g_list_last(list)->data); // GList* g_list_insert_before(GList *list, GList *sibling, gpointer data); 在链表指针sibling处前面插入data数据,NULL是最后一个的指针 list = g_list_insert_before(list, NULL, &nums[3]); g_printf("The last item should be '%d' now.\t\tResult: %d.\n", nums[3], *(gint*)g_list_last(list)->data); // #define g_list_next (list) 在list指针处的下一个指针,这个和单链表的next是一样的 g_printf("The second item should be '%d' now.\t\tResult: %d.\n", nums[1], *(gint*)g_list_next(list)->data); // #define g_list_previous (list) 这个是list指针处的前一个指针,这个是单链表无法容易做到的,双向链表中的双向优势 g_printf("The first item should be '%d' now.\t\tResult: %d.\n", nums[0], *(gint*)g_list_previous(g_list_next(list))->data); // gint g_list_index(GList *list, gconstpointer data); 查找data首次出现的位置 g_printf("The index of '%d' should be '%d' now.\t\tResult: %d.\n", nums[2], 2, g_list_index(list, &nums[2])); // gint g_list_position(GList *list, GList *llink); 返回link在list链表中的位置 g_printf("The position of the third item should be 2 now.\t\tResult: %d.\n", g_list_position(list, g_list_next(list)->next)); // guint g_list_length(GList *list); 链表长度 g_printf("The length of list should be 4 now.\t\tResult: %d.\n", g_list_length(list)); GList *lt = NULL; gint i; // GList* g_list_insert_sorted(GList *list, gpointer data, GCompareFunc func); 按照func的规则排序插入 for (i = 4; i < 10; i++) lt = g_list_insert_sorted(lt, &nums[i], sort_r);//逆向排序插入,9,8,7,6,5,4 // GList* g_list_reverse(GList *list); 翻转链表,翻转后是正序了,4,5,6,7,8,9 lt = g_list_reverse(lt); g_printf("The second half of list should be sored now.\nResult:"); // gpointer g_list_nth_data(GList *list, guint n); 返回在位置n的数据 for (i = 4; i < 10; i++) g_printf("%d,",*(gint*)(g_list_nth_data(lt, i-4))); g_printf("\n"); // GList* g_list_concat(GList *list1, GList *list2); 拼接list1和list2,这里的list2的内容并不是复制的,而是直接连接的 list = g_list_concat(list, lt); g_printf("The list should have all items which should be sored now.\nResult:"); // void g_list_foreach(GList *list, GFunc func, gpointer user_data); 调用func函数去操作list的每个元素,前面print函数是打印了list中的元素,user_data是func的第二个参数 g_list_foreach(list, print, NULL); g_printf("\n"); // GList* g_list_sort(GList *list, GCompareFunc compare_func); 将链表中的元素按照func的规则进行排序 list = g_list_sort(list, sort_r);//逆向排序 g_printf("The list should have all items which should be sored reversed now.\nResult:"); g_list_foreach(list, print, NULL); g_printf("\n"); GList *lb = NULL; // GList* g_list_copy(GList *list); 复制链表,仅仅是指针的复制,并没有进行数据的复制 lb = g_list_copy(list); g_printf("The backup list should have the same item and sequence now.\nResult:"); // GList* g_list_nth(GList *list, guint n); 返回位置n的链表指针 for (i = 0; i < 10; i++) { GList *ltmp = g_list_nth(lb, i); g_printf("%d,", *(gint*)ltmp->data); } g_printf("\n"); // GList* g_list_sort_with_data(GList *list, GCompareDataFunc compare_func, gpointer user_data); 和g_list_sort()函数一样,只是能够接受一个用户参数user_data lb = g_list_sort_with_data(lb, (GCompareDataFunc)sort, NULL); g_printf("The backup list should have all items which should be sored now.\nResult:"); g_list_foreach(lb, print, NULL); g_printf("\n"); GList *lall = NULL; lall = g_list_concat(list, lb); g_printf("The concated list should have all items now.\nResult:"); g_list_foreach(lall, print, NULL); g_printf("\n"); // GList* g_list_remove(GList *list, gconstpointer data); 删除数据data,只删除第一个出现的元素 lall = g_list_remove(lall, &nums[0]); g_printf("The list should have only one '%d' item now.\nResult:", nums[0]); g_list_foreach(lall, print, NULL); g_printf("\n"); // GList* g_list_remove_all(GList *list, gconstpointer data); 删除data,不仅仅是第一个,所有的都删除 lall = g_list_remove_all(lall, &nums[9]); g_printf("The list should not have '%d' item now.\nResult:", nums[9]); g_list_foreach(lall, print, NULL); g_printf("\n"); GList *ll = NULL; // GList* g_list_find(GList *list, gconstpointer data); 找到数据data在链表中的位置,返回元素指针 g_printf("The list should find '%d' now.\t\tResutl: %d.\n", nums[0], (ll = g_list_find(lall, &nums[0])) ? *(gint*)ll->data : -1); // GList* g_list_find_custom(GList *list, gconstpointer data, GCompareFunc func); 根据func条件查找data,如果没找到返回null g_printf("The list should not find '%d' now.\t\tResutl: %d.\n", nums[9], (ll = g_list_find_custom(lall, &nums[9], sort)) ? *(gint*)ll->data : -1); // void g_list_free(GList *list); g_list_free(lall); } int main(void) { printf("BEGIN:\n************************************************************\n"); test_list(); printf("\n************************************************************\nDONE\n"); return 0; }
linux@ubuntu:~/16021/glibdemo$ ls
Doubly_Linked_Lists.c glist hello helloworld.c slist slist.c
linux@ubuntu:~/16021/glibdemo$ gcc -o Doubly_Linked_Lists Doubly_Linked_Lists.c -lglib-2.0
linux@ubuntu:~/16021/glibdemo$ ls
Doubly_Linked_Lists Doubly_Linked_Lists.c glist hello helloworld.c slist slist.c
linux@ubuntu:~/16021/glibdemo$ ./Doubly_Linked_Lists
BEGIN:
************************************************************
The first item should be '1' now. Result: 1.
The first item should be '0' now. Result: 0.
The last item should be '2' now. Result: 2.
The last item should be '3' now. Result: 3.
The second item should be '1' now. Result: 1.
The first item should be '0' now. Result: 0.
The index of '2' should be '2' now. Result: 2.
The position of the third item should be 2 now. Result: 2.
The length of list should be 4 now. Result: 4.
The second half of list should be sored now.
Result:4,5,6,7,8,9,
The list should have all items which should be sored now.
Result:0,1,2,3,4,5,6,7,8,9,
The list should have all items which should be sored reversed now.
Result:9,8,7,6,5,4,3,2,1,0,
The backup list should have the same item and sequence now.
Result:9,8,7,6,5,4,3,2,1,0,
The backup list should have all items which should be sored now.
Result:0,1,2,3,4,5,6,7,8,9,
The concated list should have all items now.
Result:9,8,7,6,5,4,3,2,1,0,0,1,2,3,4,5,6,7,8,9,
The list should have only one '0' item now.
Result:9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,
The list should not have '9' item now.
Result:8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,
The list should find '0' now. Resutl: 0.
The list should not find '9' now. Resutl: -1.
************************************************************
DONE
linux@ubuntu:~/16021/glibdemo$