雙向鏈表與單向鏈表的區別是,從一個節點,不僅能訪問到它的下一個節點,還能訪問到它的上一個節點,其定義如下:
{
gpointer data;
GList *next;
GList *prev;
};
在這裏可以看到雙向鏈表比單向鏈表多了一個指向上一個節點的指針prev。下面給出一段雙向鏈表的演示代碼:
* file: g_list.c
* desc: 這個文件用於演示glib庫裏雙向鏈表GList的用法
* compile: gcc -o g_list g_list.c `pkg-config --cflags --libs glib-2.0`
*/
#include <glib.h>
void display_list(GList *list)
{
GList *it = NULL;
/* 遍歷鏈表 */
for (it = list; it; it = it->next) {
printf("%s", it->data);
}
printf("/n");
}
int main(int argc, char *argv[])
{
GList *list = NULL;
/*
* 向鏈表尾部追加節點
*/
list = g_list_append(list, "one ");
list = g_list_append(list, "two ");
list = g_list_append(list, "three ");
list = g_list_append(list, "four ");
list = g_list_append(list, "five ");
display_list(list);
/* 在鏈表頭部插入*/
list = g_list_prepend(list, "zero ");
display_list(list);
GList *it = NULL;
/* 查找鏈表中的節點 */
it = g_list_find(list, "two ");
printf("Find data "two ": %s/n", it->data);
int index = 0;
/* 確定鏈表指針指向鏈表中的第幾個節點 */
index = g_list_position(list, it);
printf("index of "two " is: %d/n", index);
it = g_list_nth(list, 1);
printf("%s/n", it->data);
/* 從鏈表裏刪除一個節點 */
printf("After remove data "three ", the list:/n");
list = g_list_remove(list, "three ");
display_list(list);
/* 向鏈表裏插入一個節點 */
printf("After insert string "INSERT " at index 3, the list:/n");
list = g_list_insert(list, "INSERT ", 3);
display_list(list);
/* 採用內循環遍歷鏈表節點 */
g_list_foreach(list, (GFunc)printf, NULL);
printf("/n");
GList *last = NULL;
/* 取鏈表的最後一個節點 */
last = g_list_last(list);
/* 從最後一個節點開始遍歷鏈表 */
for (it = last; it; it = it->prev) {
printf("%s", it->data);
}
printf("/n");
/* 銷燬鏈表 */
g_list_free(list);
return 0;
}
gcc -o g_list g_list.c `pkg-config --cflags --libs glib-2.0`
編譯後程序運行的結果如下:
$ ./g_list
one two three four five
zero one two three four five
Find data "two ": two
index of "two " is: 2
one
After remove data "three ", the list:
zero one two four five
After insert string "INSERT " at index 3, the list:
zero one two INSERT four five
zero one two INSERT four five
five four INSERT two one zero
現在你應該知道我爲什麼在每個字符串後面加一個空格了吧。
總結:在glib庫中,雙向鏈表的用法跟單向鏈表基本上是一致的,只是多了一個訪問上一個節點的指針prev。對於你的應用如果單向鏈表夠用,就沒有必要使用雙向鏈表,因爲這裏要增加維護一個指針的開銷。
glib庫的更多參考:
http://developer.gnome.org/doc/API/glib/index.html
http://developer.gnome.org/doc/API/2.0/glib/index.html