glib 单向链表

原文地址: http://oss.lzu.edu.cn/modules/newbb/viewtopic.php?topic_id=498&forum=13&move=next

参考地址: http://hi.baidu.com/study_together/blog/item/efa7723a86d28ffe3b87ce3c.html

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

1

创建、添加和销毁

下面的代码将初始化一个 GSList,向其添加两个条目,打印出列表的长度,然后释放它:

#include < glib.h >
#include
< stdio.h >
int main( int argc, char ** argv) {
GSList
* list = NULL;
printf(
" The list is now %d items long\n " , g_slist_length(list));
list
= g_slist_append(list, " first " );
list
= g_slist_append(list, " second " );
printf(
" The list is now %d items long\n " , g_slist_length(list));
g_slist_free(list);
return 0 ;
}

***** Output ***** 

The list is now 0 items long 
The list is now 2 items long 

2

添加然后删除数据

可以添加数据;可能还会需要将其删除。这里是一个示例:

#include < glib.h >
#include
< stdio.h >
int main( int argc, char ** argv) {
GSList
* list = NULL;
list
= g_slist_append(list, " second " );
list
= g_slist_prepend(list, " first " );
printf(
" The list is now %d items long\n " , g_slist_length(list));
list
= g_slist_remove(list, " first " );
printf(
" The list is now %d items long\n " , g_slist_length(list));
g_slist_free(list);
return 0 ;
}

***** Output ***** 

The list is now 2 items long 

The list is now 1 items long 

3

删除重复的条目 

这里是当在一个列表中有重复的条目时会发生的问题: 

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

int main( int argc, char ** argv) {
GSList
* list = NULL;
list
= g_slist_append(list, " first " );
list
= g_slist_append(list, " second " );
list
= g_slist_append(list, " second " );
list
= g_slist_append(list, " third " );
list
= g_slist_append(list, " third " );
printf(
" The list is now %d items long\n " , g_slist_length(list));
list
= g_slist_remove(list, " second " );
list
= g_slist_remove_all(list, " third " );
printf(
" The list is now %d items long\n " , g_slist_length(list));
g_slist_free(list);
return 0 ;
}

***** Output ***** 

The list is now 5 items long 
The list is now 2 items long

4

最后一个、第 n 个 和第 n 个数据

在 GSList 中有了一些条目后,可以通过不同的方式提取它们。这里是一些示例,并在 printf 语句中给出了解释。 

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

int main( int argc, char ** argv) {
GSList
* list = NULL;
list
= g_slist_append(list, " first " );
list
= g_slist_append(list, " second " );
list
= g_slist_append(list, " third " );
printf(
" The last item is '%s'\n " , g_slist_last(list) -> data);
printf(
" The item at index '1' is '%s'\n " , g_slist_nth(list, 1 ) -> data);
printf(
" Now the item at index '1' the easy way: '%s'\n " , g_slist_nth_data(list, 1 ));
printf(
" And the 'next' item after first item is '%s'\n " , g_slist_next(list) -> data);
g_slist_free(list);
return 0 ;
}

***** Output ***** 

The last item is 'third' 
The item at index '1' is 'second' 
Now the item at index '1' the easy way: 'second' 
And the 'next' item after first item is 'second' 

5

使用用户定义的类型

到现在为止我们一直在使用字符串;也就是说,我们只是将指向字符的指针放入到 GSList 中。在下面的代码示例中,

将会定义一个 Person 结构体,并将这个结构体的一些实例放入到 GSList 中:

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

typedef
struct {
char * name;
int shoe_size;
} Person;
int main( int argc, char ** argv) {
GSList
* list = NULL;
Person
* tom = (Person * )malloc( sizeof (Person));
tom
-> name = " Tom " ;
tom
-> shoe_size = 12 ;
list
= g_slist_append(list, tom);
Person
* fred = g_new(Person, 1 ); // allocate memory for one Person struct
fred -> name = " Fred " ;
fred
-> shoe_size = 11 ;
list
= g_slist_append(list, fred);
printf(
" Tom's shoe size is '%d'\n " , ((Person * )list -> data) -> shoe_size);
printf(
" The last Person's name is '%s'\n " , ((Person * )g_slist_last(list) -> data) -> name);
g_slist_free(list);
free(tom);
g_free(fred);
return 0 ;
}

***** Output ***** 

Tom's shoe size is '12' 
The last Person's name is 'Fred' 

6

组合、反转,等等 

GSList 附带了一些便利的工具,可以连接和反转列表。这里是它们的工作方式: 

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

int main( int argc, char ** argv) {
GSList
* list1 = NULL;
list1
= g_slist_append(list1, " first " );
list1
= g_slist_append(list1, " second " );
GSList
* list2 = NULL;
list2
= g_slist_append(list2, " third " );
list2
= g_slist_append(list2, " fourth " );
GSList
* both = g_slist_concat(list1, list2);
printf(
" The third item in the concatenated list is '%s'\n " , g_slist_nth_data(both, 2 ));
GSList
* reversed = g_slist_reverse(both);
printf(
" The first item in the reversed list is '%s'\n " , reversed -> data);
g_slist_free(reversed);
return 0 ;
}

***** Output ***** 

The third item in the concatenated list is 'third' 
The first item in the reversed list is 'fourth' 

7

简单遍历 

这里是遍历 GSList 中所有内容的一个直观方法: 

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

int main( int argc, char ** argv) {
GSList
* list = NULL, * iterator = NULL;
list
= g_slist_append(list, " first " );
list
= g_slist_append(list, " second " );
list
= g_slist_append(list, " third " );
for (iterator = list; iterator; iterator = iterator -> next) {
printf(
" Current item is '%s'\n " , iterator -> data);
}
g_slist_free(list);
return 0 ;
}

***** Output ***** 

Current item is 'first' 
Current item is 'second' 
Current item is 'third' 

迭代器(iterator)

8

使用函数进行高级遍历

  遍历列表的另一种方法是使用 g_slist_foreach,并提供一个将为列表中的每一个条目调用的函数。 

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

void print_iterator(gpointer item, gpointer prefix) {
printf(
" %s %s\n " , prefix, item);
}
void print_iterator_short(gpointer item) {
printf(
" %s\n " , item);
}
int main( int argc, char ** argv) {
GSList
* list = g_slist_append(NULL, g_strdup( " first " ));
list
= g_slist_append(list, g_strdup( " second " ));
list
= g_slist_append(list, g_strdup( " third " ));
printf(
" Iterating with a function:\n " );
g_slist_foreach(list, print_iterator,
" --> " );
printf(
" Iterating with a shorter function:\n " );
g_slist_foreach(list, (GFunc)print_iterator_short, NULL);
printf(
" Now freeing each item\n " );
g_slist_foreach(list, (GFunc)g_free, NULL);
g_slist_free(list);
return 0 ;
}

***** Output ***** 

Iterating with a function: 
--> first 
--> second 
--> third 
Iterating with a shorter function: 
first 
second 
third 
Now freeing each item 

9

使用 GCompareFunc 排序

可以通过提供一个知道如何比较列表中条目的函数来对 GSLit 进行排序。下面的示例展示了对字符串列表进行排序的一种方法:

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

gint my_comparator(gconstpointer item1, gconstpointer item2) {
return g_ascii_strcasecmp(item1, item2);
}
int main( int argc, char ** argv) {
GSList
* list = g_slist_append(NULL, " Chicago " );
list
= g_slist_append(list, " Boston " );
list
= g_slist_append(list, " Albany " );
list
= g_slist_sort(list, (GCompareFunc)my_comparator);
printf(
" The first item is now '%s'\n " , list -> data);
printf(
" The last item is now '%s'\n " , g_slist_last(list) -> data);
g_slist_free(list);
return 0 ;
}

***** Output ***** 

The first item is now 'Albany' 
The last item is now 'Chicago'

10

查找元素 

有一些方法可以在 GSList 查找元素。已经介绍了如何简单地遍历列表的全部内容,比较每个条目,直到找到了目标条目。

如果已经拥有了要寻找的数据,而只是想要获得它在列表中的位置,那么可以使用 g_slist_find。最后,可以使用 g_slist_find_custom,

它允许您使用一个函数来检查列表中的每一个条目。下面展示了 g_slist_find 和 g_slist_find_custom: 

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

gint my_finder(gconstpointer item) {
return g_ascii_strcasecmp(item, " second " );
}
int main( int argc, char ** argv) {
GSList
* list = g_slist_append(NULL, " first " );
list
= g_slist_append(list, " second " );
list
= g_slist_append(list, " third " );
GSList
* item = g_slist_find(list, " second " );
printf(
" This should be the 'second' item: '%s'\n " , item -> data);
item
= g_slist_find_custom(list, NULL, (GCompareFunc)my_finder);
printf(
" Again, this should be the 'second' item: '%s'\n " , item -> data);
item
= g_slist_find(list, " delta " );
printf(
" 'delta' is not in the list, so we get: '%s'\n " , item ? item -> data : " (null) " );
g_slist_free(list);
return 0 ;
}

***** Output ***** 

This should be the 'second' item: 'second' 
Again, this should be the 'second' item: 'second' 
'delta' is not in the list, so we get: '(null)'

11

通过插入进行高级添加

既然已经接触过几次 GCompareFunc,一些更有趣的插入操作会更有意义。使用 g_slist_insert 可以将条目插入到指定的位置,

使用 g_slist_insert_before 可以将条目插入到特定位置之前,使用 g_slist_insert_sorted 可以进行有序插入。这里是样例:  

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

int main( int argc, char ** argv) {
GSList
* list = g_slist_append(NULL, " Anaheim " ), * iterator = NULL;
list
= g_slist_append(list, " Elkton " );
printf(
" Before inserting 'Boston', second item is: '%s'\n " , g_slist_nth(list, 1 ) -> data);
g_slist_insert(list,
" Boston " , 1 );
printf(
" After insertion, second item is: '%s'\n " , g_slist_nth(list, 1 ) -> data);
list
= g_slist_insert_before(list, g_slist_nth(list, 2 ), " Chicago " );
printf(
" After an insert_before, third item is: '%s'\n " , g_slist_nth(list, 2 ) -> data);
list
= g_slist_insert_sorted(list, " Denver " , (GCompareFunc)g_ascii_strcasecmp);
printf(
" After inserting 'Denver', here's the final list:\n " );
g_slist_foreach(list, (GFunc)printf, NULL);
g_slist_free(list);
return 0 ;
}

***** Output ***** 

Before inserting 'Boston', second item is: 'Elkton ' 
After insertion, second item is: 'Boston ' 
After an insert_before, third item is: 'Chicago ' 
After inserting 'Denver', here's the final list: 
Anaheim Boston Chicago Denver Elkton 


12

自定义数据结构排序 (根据字符)

#include <glib.h>
#include
<stdio.h>
#include
<stdlib.h>
typedef
struct {
char* name;
int shoe_size;
} Person;

gint my_comparator(gconstpointer item1, gconstpointer item2) {
return g_ascii_strcasecmp(((Person*)item1)->name, ((Person*)item2)->name);
}

int main(int argc, char** argv) {
GSList
* list = NULL;

Person
* tom = (Person*)malloc(sizeof(Person));
tom
->name = "Tom";
tom
->shoe_size = 12;
list
= g_slist_append(list, tom);

Person
* fred = g_new(Person, 1); // allocate memory for one Person struct
fred->name = "Fred";
fred
->shoe_size = 11;
list
= g_slist_append(list, fred);

Person
* god = g_new(Person, 1); // allocate memory for one Person struct
god->name = "zod";
god
->shoe_size = 15;
list
= g_slist_append(list, god);


list
= g_slist_sort(list, (GCompareFunc)my_comparator);

printf(
"Tom's shoe size is '%d'\n", ((Person*)list->data)->shoe_size);
printf(
"The last Person's name is '%s'\n", ((Person*)g_slist_last(list)->data)->name);
g_slist_free(list);
free(tom);
g_free(fred);
g_free(god);
return 0;
}


   ***** Output *****
Tom's shoe size is '11'
The last Person's name is 'zod'

13 自定义数据结构排序(根据数字)

#include <glib.h>
#include
<stdio.h>
#include
<stdlib.h>
typedef
struct {
char* name;
int shoe_size;
} Person;

gint my_comparator(gconstpointer item1, gconstpointer item2) {
if(((Person*)item1)->shoe_size > ((Person*)item2)->shoe_size)
{
return 1;
}
else
{
return 0;
}
// return g_ascii_strcasecmp(((Person*)item1)->name, ((Person*)item2)->name);
}

int main(int argc, char** argv) {
GSList
* list = NULL;

Person
* tom = (Person*)malloc(sizeof(Person));
tom
->name = "Tom";
tom
->shoe_size = 10;
list
= g_slist_append(list, tom);

Person
* fred = g_new(Person, 1); // allocate memory for one Person struct
fred->name = "yred";
fred
->shoe_size = 11;
list
= g_slist_append(list, fred);

Person
* god = g_new(Person, 1); // allocate memory for one Person struct
god->name = "zod";
god
->shoe_size = 15;
list
= g_slist_append(list, god);


list
= g_slist_sort(list, (GCompareFunc)my_comparator);

printf(
"Tom's shoe size is '%d'\n", ((Person*)list->data)->shoe_size);
printf(
"The last Person's name is '%s'\n", ((Person*)g_slist_last(list)->data)->name);
g_slist_free(list);
free(tom);
g_free(fred);
g_free(god);
return 0;
}

*******output*******
Tom's shoe size is '10'
The last Person's name is 'zod'

  

  

你可能感兴趣的:(lib)