首页 > 其他分享 >【glibc】glib库双向链表GList介绍

【glibc】glib库双向链表GList介绍

时间:2024-01-22 10:55:24浏览次数:26  
标签:glib glibc list two GList 链表 printf 节点

在上一篇文章里我介绍了glib库中单向链表的用法,这篇文章介绍glib库双向链表的用法,还是沿用上一篇文章的风格,采用在代码中加入注释来说明代码,最后贴出程序的运行结果,然后加以少量说明。


双向链表与单向链表的区别是,从一个节点,不仅能访问到它的下一个节点,还能访问到它的上一个节点,其定义如下:

struct GList
{
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;}

在linux下使用下面的命令编译:

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,glibc,list,two,GList,链表,printf,节点
From: https://www.cnblogs.com/opensmarty/p/17979552

相关文章

  • 【glibc】glib库数组GArray介绍
    glib库中的数组GArray类型很像C++标准容器库中的vector容器。要使用glib库中的数组中需要声明一个指向GArray类型的指针。GArray的定义如下:structGArray{gchar*data;guintlen;};然后就可以在这个数组前或者数组后添加数据,添加数据的时候数组也会像C++中的vector容器......
  • 【glibc】glib库hash表GHashTable介绍
    hash表是一种提供key-value访问的数据结构,通过指定的key值可以快速的访问到与它相关联的value值。hash表的一种典型用法就是字典,通过单词的首字母能够快速的找到单词。关于hash表的详细介绍请查阅数据结构的相关书籍,我这里只介绍glib库中hash表的基本用法。要使用一个hash表首先必......
  • 【glibc】glib库队列GQueue介绍
    队列是一种向最后添加条目,从最前删除条目的数据结构,这种数据结构在处理按顺序到达的数据是很有用。glib库提供的队列GQueue是一个双端队列,它的实现基础是双向链表,所以它支持在队列的两端进行添加和删除,也支持很多其它的操作,比如在队列中进行插入和删除,但是我不推荐使用这样的功能......
  • 链表
    1.设计链表力扣707-单链表classListNode{intval;ListNodenext;ListNode(intval){this.val=val;}}classMyLinkedList{intsize;ListNodehead;//虚拟头节点publicMyLinkedList(){size=0;head=......
  • C++U3-第11课-单、双链表
    学习目标 链表概念计算机存储结构 单链表 实现单链表       删除 插入节点  双向链表  实现双链表         [【数据结构-链表】猴子选大王] 【题意分析】通过循环报数的方式每一次剔除......
  • spring--CGLIB动态代理的实现原理
    CGLIB(CodeGenerationLibrary)是一个强大的、高性能、高质量的代码生成库,它可以在运行时扩展Java类和实现Java接口。CGLIB动态代理是基于继承的方式来实现的,它不需要接口,可以代理普通类。以下是CGLIB动态代理的实现原理:继承:CGLIB动态代理通过继承目标类来创建子类,并在......
  • spring--JDK动态代理和CGLIB代理的区别
    JDK动态代理和CGLIB代理是Java中常用的两种动态代理实现方式,它们各有特点和适用场景:JDK动态代理:JDK动态代理是基于接口的代理方式,它使用Java反射机制来创建代理对象,并要求目标对象实现一个或多个接口。在代理过程中,JDK动态代理会创建一个实现了目标对象所有接口的代......
  • 148.排序链表
    1.题目介绍给你链表的头结点head,请将其按升序排列并返回排序后的链表。示例1:输入:head=[4,2,1,3]输出:[1,2,3,4]2.题解在147.对链表进行插入排序中我们使用插入排序的方式对于链表进行排序插入排序的时间复杂度是O(n^2),其中n是链表的长度。这道题考虑时间复杂度......
  • linux内核链表
    linux内核的链表实现定义链表节点和初始化LIST_HEAD_INIT宏通过将next和prev都指向自身,来对节点进行初始化LIST_HEAD宏定义一个structlist_head类型的节点,并使用LIST_HEAD_INIT宏进行初始化点击查看代码structlist_head{ structlist_head*next,*prev;};#defineL......
  • /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found问题解决
    有一个go实现的项目代码最近有更新,自己在开发环境上手动构建并运行都没有问题(构建和运行时相同环境,肯定没有问题^_^)。后面通过jenkins构建镜像也没有问题,运行时却报错 之前的版本在jenkins上构建也是成功的,后沟通得知jenkins集群版本最近有更新 那么,大概知道原因了,由于jenk......