Chinaunix首页 | 论坛 | 博客
  • 博客访问: 223017
  • 博文数量: 28
  • 博客积分: 398
  • 博客等级: 一等列兵
  • 技术积分: 1109
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-07 22:28
文章分类
文章存档

2017年(1)

2014年(3)

2013年(7)

2012年(4)

2011年(13)

分类: C/C++

2013-09-26 15:42:45

网上的例子大多只是基于字符串的链表结合使用方法,特提供一个基于结构体的使用,同时对不常用的 自定义排序g_list_sort , 自定义查找 g_list_find_custom使用。
以下是实例代码:

点击(此处)折叠或打开

  1. /*
  2.  * file: g_list.c
  3.  * desc: 这个文件用于演示glib库里双向链表GList的用法
  4.  * compile: gcc -o g_list g_list.c `pkg-config --cflags --libs glib-2.0`
  5.  */

  6. #include <glib.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>

  10. typedef struct stu{
  11.     long id;
  12.     int age;
  13.     char *name;
  14. }person_t;


  15. /* 构建一个节点 */
  16. person_t * get_person_node( int id, int age, char *name)
  17. {
  18.     person_t *pstu = (person_t *)calloc( sizeof(person_t), 1 );
  19.     if ( pstu == NULL ) return NULL;
  20.     pstu->id = id;
  21.     pstu->age = age;
  22.     pstu->name = (char *)strdup( (const char*)name );

  23.     return pstu;
  24. }

  25. /*遍历整个链表,打印显示*/
  26. void display_list(GList *list)
  27. {
  28.     GList *it = NULL;
  29.     person_t *pstu = NULL;

  30.     /* 遍历链表 */
  31.     for (it = list; it; it = it->next) {
  32.         pstu = it->data;
  33.         printf( "id=%d, age=%d, name=%s\r\n", pstu->id, pstu->age, pstu->name );
  34.     }

  35.     printf("\n");
  36. }

  37. /*删除一个节点*/
  38. GList *list_remove_by_name(GList *list, char *name )
  39. {
  40.     GList *it = NULL;
  41.     person_t *pstu = NULL;

  42.     /* 遍历链表 */
  43.     for (it = list; it; it = it->next) {
  44.         pstu = it->data;
  45.         if ( memcmp(pstu->name, name, strlen(name)) == 0)
  46.         {
  47.             //fprintf(stdout, "delete node:%s\r\n", pstu->name );
  48.             free( pstu->name );
  49.             free( pstu );
  50.             //GList *ret_list = g_list_remove(list,it);
  51.             GList *ret_list = g_list_remove_link(list,it);
  52.         }
  53.     }
  54.     return list;
  55. }

  56. /*释放链表,及其结点*/
  57. void free_list_data(GList *list)
  58. {
  59.     GList *it = NULL;
  60.     person_t *pstu = NULL;

  61.     /* 遍历链表 */
  62.     for (it = list; it; it = it->next) {
  63.         pstu = it->data;
  64.         free( pstu->name );
  65.     }

  66.     g_list_free(list);

  67.     printf("free list success \n");
  68. }

  69. /*按照名称比较*/
  70. int my_comparator_by_name(gconstpointer item1, gconstpointer item2) {
  71.      person_t *psrc = (person_t *)(item1);
  72.      person_t *pdst = (person_t *)(item2);
  73.      //fprintf(stdout, "src:%s,dst:%s\r\n", psrc->name, pdst->name );
  74.      if ( memcmp(psrc->name,pdst->name,strlen(pdst->name) ) == 0 )
  75.          return 0;
  76.      else
  77.          return -1;
  78. }

  79. /*按照年龄比较*/
  80. int my_comparator_by_age(gconstpointer item1, gconstpointer item2) {
  81.      person_t *psrc = (person_t *)(item1);
  82.      person_t *pdst = (person_t *)(item2);
  83.      if ( psrc->age > pdst->age )
  84.          return 1;
  85.      else if ( psrc->age < pdst->age )
  86.          return -1;
  87.      else
  88.          return 0;
  89. }


  90. int main(int argc, char *argv[])
  91. {
  92.     GList *list = NULL;

  93.     /* 向链表尾部追加节点 */
  94.     list = g_list_append(list, get_person_node(1,18,"hby") );
  95.     list = g_list_append(list, get_person_node(2,42,"tli") );
  96.     list = g_list_append(list, get_person_node(3,39,"gl") );
  97.     fprintf(stdout, "初始化链表输出.......\r\n");
  98.     display_list(list);

  99.     /*指定位置插入节点*/
  100.     list = g_list_insert(list, get_person_node(0,89,"sf"), 0 );
  101.     /*尾部追加*/
  102.     list = g_list_append(list, get_person_node(4,76,"fsd") );
  103.     fprintf(stdout, "插入更新后的链表输出.......\r\n");
  104.     display_list(list);

  105.     /*删除指定结点*/
  106.     list = list_remove_by_name(list, "tli");
  107.     list = list_remove_by_name(list, "hby");
  108.     fprintf(stdout, "删除结点后输出 [tli, hby].......\r\n");
  109.     display_list(list);


  110.     fprintf(stdout, "反转方式输出链表.......\r\n");
  111.     /* 从最后一个节点开始遍历链表 */
  112.     GList *it = NULL;
  113.     person_t *pstu = NULL;
  114.     it = g_list_last(list);
  115.     for (; it; it = it->prev) {
  116.         pstu = it->data;
  117.         fprintf( stdout, "id=%d, age=%d, name=%s\r\n", pstu->id, pstu->age, pstu->name );
  118.     }
  119.     fprintf(stdout, "\r\n");

  120.     /*自定义函数排序*/
  121.     list = g_list_insert(list, get_person_node(8,32,"skds"), 0 );
  122.     list = g_list_insert(list, get_person_node(6,45,"ff"), 0 );
  123.     list = g_list_sort(list, my_comparator_by_age);
  124.     fprintf(stdout, "自定义排序(按照年龄大小)后输出.......\r\n");
  125.     display_list(list);

  126.     /*自定义函数查找*/
  127.     fprintf(stdout, "自定义函数(按照姓名)查找.......\r\n");
  128.     person_t sfind;
  129.     memset(&sfind, 0x00, sizeof(person_t) );
  130.     sfind.name = g_strdup("fsd");
  131.     GList *item = g_list_find_custom(list,&sfind, my_comparator_by_name);
  132.     if ( item )
  133.     { // 查找到
  134.         person_t *pdata = item->data;
  135.         fprintf(stdout, "find name[%s] age is:%d, id is:%d\r\n",
  136.                 pdata->name, pdata->age, pdata->id );
  137.     }
  138.     else
  139.         fprintf(stdout, "find name[%s] NULL\r\n", sfind.name );
  140.     free(sfind.name);
  141.     fprintf(stdout, "\r\n");


  142.     /* 销毁链表 */
  143.     fprintf(stdout, "释放链表及结点内存.......\r\n");
  144.     free_list_data(list);

  145.     return 0;
  146. }



===============================================================
编译:
#gcc -o g_list g_list.c `pkg-config --cflags --libs glib-2.0`

运行输出:
10122-hby-2:/home/hby/work/test/glibc # ./g_list 
初始化链表输出.......
id=1, age=18, name=hby
id=2, age=42, name=tli
id=3, age=39, name=gl

插入更新后的链表输出.......
id=0, age=89, name=sf
id=1, age=18, name=hby
id=2, age=42, name=tli
id=3, age=39, name=gl
id=4, age=76, name=fsd

删除结点后输出 [tli, hby].......
id=0, age=89, name=sf
id=3, age=39, name=gl
id=4, age=76, name=fsd

反转方式输出链表.......
id=4, age=76, name=fsd
id=3, age=39, name=gl
id=0, age=89, name=sf

自定义排序(按照年龄大小)后输出.......
id=8, age=32, name=skds
id=3, age=39, name=gl
id=6, age=45, name=ff
id=4, age=76, name=fsd
id=0, age=89, name=sf

自定义函数(按照姓名)查找.......
find name[fsd] age is:76, id is:4

释放链表及结点内存.......
free list success 
阅读(7844) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~