四、Glib库单链表

1 单链表结构体

typedef struct _GSList GSList;

struct _GSList
{
  gpointer data;
  GSList *next;
};

2 单链表相关函数总结

2.1.1 链表末尾插入元素

GSList* g_slist_append (GSList           *list,
					    gpointer          data);
  • list:一个单链表
  • data:一个数据的指针
  • Note:该函数会遍历链表到末尾,插入元素,最后返回值等于变量1给定的单链表。格外注意的是,这个list不一定是一个单链表的开头,可以是中间某个元素,如果list是中间某个元素,则返回值也是中间某个元素。

2.1.2 向前插入元素

GSList*  g_slist_prepend (GSList *list,
					      gpointer data);
  • Note:list之前如果有数据,会替换掉该数据,返回list之前的指针。

2.1.3 指定节点之前插入元素

GSList*  g_slist_insert_before (GSList           *slist,
				            	GSList           *sibling,
					 		    gpointer          data)
  • slist:一个链表
  • sibling:在那个节点之前要插入数据
  • data:数据
  • Returns:返回一个新的头指针
  • Note:如果slist = NULL,sibling = NULL,就会创建一个新的单链表。

2.1.4 指定位置插入元素

GSList*  g_slist_insert (GSList           *list,
					     gpointer          data,
					     gint              position)
  • 如果position大于链表或者是负数,就在链表末尾插入数据。

2.1.5 根据排序函数插入元素

GSList*  g_slist_insert_sorted  (GSList           *list,
					             gpointer          data,
					             GCompareFunc      func)

2.2 查找

2.2.1 根据位置查找链表节点地址

GSList*  g_slist_nth (GSList *list,
					  guint   n);
  • list:一个单链表
  • n:这个单链接的第n个位置
  • Note:值得注意的是,第n个位置,是从输入参数list数起,不是单链表的头结点数起。如果数到结尾,则返回NULL。

2.2.2 根据data查找链表节点位置

gint     g_slist_index (GSList           *list,
					    gconstpointer     data);

2.2.3 根据用户提供func和data查询节点

GSList*  g_slist_find_custom  (GSList           *list,
					           gconstpointer     data,
					           GCompareFunc      func);
typedef gint  (*GCompareFunc)         (gconstpointer  a,
                                       gconstpointer  b);
  • a:链表的list->data
  • b:参数2的data
  • fun return:如果返回0,就把该节点作为g_slist_find_custom返回值。

2.2.4 根据节点查询位置

gint     g_slist_position (GSList           *list,
					       GSList           *llink);

2.3 反转链表

GSList*  g_slist_reverse (GSList *list)
  • Note:从给定的list开始到末尾NULL,开始翻转。

2.4 单链表复制

GSList*  g_slist_copy (GSList           *list);
  • Note:重新创建了一个单链表,原先list的data地址和新返回list的data地址一样。
    请添加图片描述

2.5 通过比较data删除节点

/*删除所有相同data节点*/
GSList*  g_slist_remove_all        (GSList           *list,
					                gconstpointer     data);
/*如果有n个相同data的,则删除第一个相同节点*/
GSList*  g_slist_remove  (GSList           *list,
					      gconstpointer     data)

2.6 排序

GSList*  g_slist_sort (GSList           *list,
					   GCompareFunc      compare_func);
typedef gint (*GCompareFunc) (gconstpointer  a,
                              gconstpointer  b);

根据compare_func返回值进行排序,如果返回值等于0,a和b的值相等。如果a大于b,则返回负数/负数,反则正数/负数。

GSList*  g_slist_sort_with_data  (GSList           *list,
					              GCompareDataFunc  compare_func,
					              gpointer          user_data)

暂时没有发现user_data用处,目前认为两个函数作用相同。

2.7 遍历链表data

void  g_slist_foreach  (GSList           *list,
					    GFunc             func,
					    gpointer          user_data);
typedef void  (*GFunc)  (gpointer       data,
                         gpointer       user_data);

2.8 链表拼接

GSList*  g_slist_concat (GSList           *list1,
					     GSList           *list2)

3 代码

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

#define SIZE 10
#define NUMBER_MAX 99

static gint array[SIZE] = {11, 32, 23, 83, 92, 83, 92, 80, 81, 38};

static void test_slist_1(void);
static void test_slist_2(void);
static void test_slist_3(void);
static void test_slist_4(void);
static void test_slist_5(void);
static void test_slist_6(void);

int
main(int argc, char *argv[]){

  //test_slist_1();
  test_slist_6();

  return 0;
}

static void
slist_print(GSList *st){
  g_print("Read slist Begin:\n");
  while (st){
    g_print("%d, ",GPOINTER_TO_INT(st->data));
    st = g_slist_nth(st, 1);
  }
  g_print("\nRead slist Done\n");
}

static void
test_slist_1(void){
  GSList *slist = NULL;
  GSList *st = NULL; 
  gint nums[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  gint i;
  
  for(i = 0; i < 10; i++){
    /* 链表末尾增加一个新的元素 */
    slist = g_slist_append(slist, &nums[i]);
  }
  st = slist;
  g_print("Read slist Begin:\n");
  while (st){
    g_print("%d, ", *(gint *)st->data);
    st = g_slist_nth(st, 1);
  }
  g_print("\nRead slist Done\n");

  /* 翻转链表 */
  g_print("Reserve Begin:\n");
  //slist = slist->next;
  slist = g_slist_reverse(slist);
  st = slist;
  while(st){
    g_print("%d, ",*(gint *)st->data);
    st = g_slist_nth(st, 1);
  }
  g_print("\nReserve Done\n");

  /*向前插入元素*/
  slist = g_slist_prepend(slist->next, &nums[0]);
  st = slist;
  g_print("Read slist Begin:\n");
  while (st){
    g_print("%d, ", *(gint *)st->data);
    st = g_slist_nth(st, 1);
  }
  g_print("\nRead slist Done\n");

  /*最后释放链表*/
  g_slist_free(slist);
}

static void
test_slist_2(void){
  GSList *slist = NULL;
  GSList *st;
  gint nums[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

  /* 在NULL中插入1, 相当于创建了一个链表slist,并且地一个数据是1 */
  slist = g_slist_insert_before(NULL, NULL, &nums[0]);
  slist = g_slist_insert(slist, &nums[1], 1);//尾插1,链表数据:0 , 1
  slist_print(slist);
  slist = g_slist_insert_before(slist, slist->next, &nums[3]);
  slist_print(slist);
  slist = g_slist_insert(slist, &nums[2], 1);
  slist_print(slist);
  /* 因为末尾是NULL, 在末尾插入 6 */
  slist = g_slist_insert_before(slist, NULL, &nums[6]);
  slist_print(slist);

  /* 复制链表 */
  st = g_slist_copy(slist);
  g_print("slist data pointer = %p\nst data pointer = %p", slist->data, st->data);

  g_slist_free(st);
  g_slist_free(slist);
}

static void
test_slist_3(void){
  GSList *slist = NULL;
  GSList *st = NULL;
  gint nums[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  gint i;

  const gpointer n = nums;

  for(i = 0; i < 10; i++){
    /* 链表末尾增加一个新的元素 */
    slist = g_slist_append(slist, &nums[i]);
    slist = g_slist_append(slist, &nums[i]);
  }

  /* 返回链表个数 */
  g_print("This GSList length is %d\n", g_slist_length(slist));
  /* 删除所有相同 */
  g_slist_remove_all(slist, &nums[1]);
  /* 删除第一个相同 */
  g_slist_remove(slist, &nums[2]);
  slist_print(slist);

  g_slist_free(slist);
}

static gint
find_num(gconstpointer l, gconstpointer data){
  return *(gint*)l - GPOINTER_TO_INT(data);
}

static void
test_slist_4(void){
  GSList *slist = NULL;
  GSList *st = NULL;
  gint nums[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  gint i;

  for(i = 0; i < 10; i++){
    slist = g_slist_append(slist, &nums[i]);
  }

  i = g_slist_index(slist, &nums[8]);
  g_print("nums[8] index = %d\n", i);

  st = g_slist_find_custom(slist, GINT_TO_POINTER(1), find_num);
  g_print("position = %d\n", g_slist_position(slist, st));
}

gint times = 0;

static gint
sort_r(gconstpointer p1, gconstpointer p2){
  gint32 a, b;
  a = GPOINTER_TO_INT(p1);
  b = GPOINTER_TO_INT(p2);
  times++;
  g_print("a = %d b = %d   %d\n",a, b, times);
  return (a > b ? +1 : a == b ? 0 : -1);
}

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 void
test_slist_5(void)
{
  GSList *slist = NULL;
  gint i;

  for (i = 0; i < SIZE; i++)
      slist = g_slist_append(slist, GINT_TO_POINTER(array[i]));
  slist = g_slist_sort(slist, sort_r);//使用sort函数排列链表
  slist_print(slist);

  //slist = g_slist_sort_with_data(slist, (GCompareDataFunc)sort_r, NULL);
  slist_print(slist);
  g_slist_free(slist);
}

static void
print(gpointer p1, gpointer p2){
  g_print("%d, ", GPOINTER_TO_INT(p1));
}

static void
test_slist_6(void){
  GSList *slist = NULL;
  GSList *st = NULL;
  GSList *sc = NULL;
  gint i;

  for(i = 0; i < SIZE; i++){
    /* 按排序规则插入元素 */
    slist = g_slist_insert_sorted(slist, GINT_TO_POINTER(array[i]), sort);
    st = g_slist_insert_sorted_with_data(st, GINT_TO_POINTER(array[i]), sort_r, NULL);
  }

  sc = g_slist_concat(slist, st);

  g_slist_foreach(sc, print, NULL);

  g_print("\n");
}

参考1:示例代码参考博客
参考2:Glib Reference Mannual

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值