4_11_GLib库入门与实践_序列

简介

GLib序列,是这样一种数据结构,它具有和链表一样的API函数,但内部却是用二叉树实现,因此这个数据结构既有链表操作的便利,又有二叉树查找的高效。

数据结构

序列有两个常用的数据结构,序列本身和迭代器,这两者都是内部不透明的结构体,可以作为一个整体使用它,但无法访问其内部成员变量。

typedef struct _GSequence GSequence;

typedef struct _GSequenceNode  GSequenceIter;

函数列表

GSequence * 	g_sequence_new ()
void 	g_sequence_free ()
gint 	g_sequence_get_length ()
gboolean 	g_sequence_is_empty ()
void 	g_sequence_foreach ()
void 	g_sequence_foreach_range ()
void 	g_sequence_sort ()
void 	g_sequence_sort_iter ()
GSequenceIter * 	g_sequence_get_begin_iter ()
GSequenceIter * 	g_sequence_get_end_iter ()
GSequenceIter * 	g_sequence_get_iter_at_pos ()
GSequenceIter * 	g_sequence_append ()
GSequenceIter * 	g_sequence_prepend ()
GSequenceIter * 	g_sequence_insert_before ()
void 	g_sequence_move ()
void 	g_sequence_swap ()
GSequenceIter * 	g_sequence_insert_sorted ()
GSequenceIter * 	g_sequence_insert_sorted_iter ()
void 	g_sequence_sort_changed ()
void 	g_sequence_sort_changed_iter ()
void 	g_sequence_remove ()
void 	g_sequence_remove_range ()
void 	g_sequence_move_range ()
GSequenceIter * 	g_sequence_search ()
GSequenceIter * 	g_sequence_search_iter ()
GSequenceIter * 	g_sequence_lookup ()
GSequenceIter * 	g_sequence_lookup_iter ()
gpointer 	g_sequence_get ()
void 	g_sequence_set ()
gboolean 	g_sequence_iter_is_begin ()
gboolean 	g_sequence_iter_is_end ()
GSequenceIter * 	g_sequence_iter_next ()
GSequenceIter * 	g_sequence_iter_prev ()
gint 	g_sequence_iter_get_position ()
GSequenceIter * 	g_sequence_iter_move ()
GSequence * 	g_sequence_iter_get_sequence ()
gint 	g_sequence_iter_compare ()
GSequenceIter * 	g_sequence_range_get_midpoint ()

函数功能分类

序列功能相关的函数较多,但可以分为两类,序列操作函数和迭代器操作函数,其功能分类如下。

序列操作函数

创建
GSequence * g_sequence_new ()

释放
void g_sequence_free ()

测长
gint g_sequence_get_length ()

判空
gboolean g_sequence_is_empty ()

遍历
void g_sequence_foreach ()
void g_sequence_foreach_range ()

排序
void g_sequence_sort ()
void g_sequence_sort_changed ()

移动
void g_sequence_move ()
void g_sequence_move_range ()

交换
void g_sequence_swap ()

移除
void g_sequence_remove ()
void g_sequence_remove_range ()

迭代器类函数

插入
GSequenceIter * g_sequence_append ()
GSequenceIter * g_sequence_prepend ()
GSequenceIter * g_sequence_insert_before ()
GSequenceIter * g_sequence_insert_sorted ()
GSequenceIter * g_sequence_insert_sorted_iter ()

访问
GSequenceIter * g_sequence_iter_next ()
GSequenceIter * g_sequence_iter_prev ()

移动
GSequenceIter * g_sequence_iter_move ()

比较
gint g_sequence_iter_compare ()

判断
gboolean g_sequence_iter_is_begin ()
gboolean g_sequence_iter_is_end ()

获取值
gpointer g_sequence_get ()

设置值
void g_sequence_set ()

搜索
GSequenceIter * g_sequence_search ()
GSequenceIter * g_sequence_search_iter ()

查找
GSequenceIter * g_sequence_lookup ()
GSequenceIter * g_sequence_lookup_iter ()

排序
void g_sequence_sort_iter ()
void g_sequence_sort_changed_iter ()

信息获取
GSequenceIter * g_sequence_range_get_midpoint ()
GSequenceIter * g_sequence_get_begin_iter ()
GSequenceIter * g_sequence_get_end_iter ()
GSequenceIter * g_sequence_get_iter_at_pos ()
gint g_sequence_iter_get_position ()
GSequence * g_sequence_iter_get_sequence ()

函数功能说明及综合演示

函数功能说明

序列操作函数

// 创建
// 创建一个序列,可以指定节点销毁函数,当序列释放或某个节点被移出序列时,释放函数将被调用以释放节点内存。
GSequence * 	g_sequence_new ()

// 释放
// 释放一个序列,如果在序列创建时指定了数据销毁函数,则对所有节点分别调用一次数据销毁函数
void 	g_sequence_free ()

// 测长
// 获取序列的长度
gint 	g_sequence_get_length ()

// 判空
// 判断序列是否为空
gboolean 	g_sequence_is_empty ()

// 遍历
// 用户指定遍历函数或者指定遍历范围遍历
// 注意:遍历函数不可修改序列节点的值
void 	g_sequence_foreach ()
void 	g_sequence_foreach_range ()

// 排序
void 	g_sequence_sort ()
void 	g_sequence_sort_changed ()

// 移动
// 将指定节点或节点范围移动到指定位置
void 	g_sequence_move ()
void 	g_sequence_move_range ()

// 交换
// 交换两个序列节点,这两个节点可以不在一个序列内
void 	g_sequence_swap ()

// 移除
// 从序列移出一个节点
// 从序列移出一个节点范围
// 当g_sequence_new时指定了数据销毁函数,移出节点时,数据销毁函数会被调到
void 	g_sequence_remove ()
void 	g_sequence_remove_range ()

迭代器操作函数

// 插入
// 尾插、前插、指定位置插入新元素,插入并排序
GSequenceIter * 	g_sequence_append ()
GSequenceIter * 	g_sequence_prepend ()
GSequenceIter * 	g_sequence_insert_before ()
GSequenceIter * 	g_sequence_insert_sorted ()
GSequenceIter * 	g_sequence_insert_sorted_iter ()

// 访问
// 下一个迭代器节点
GSequenceIter * 	g_sequence_iter_next ()
// 下一个迭代器节点
GSequenceIter * 	g_sequence_iter_prev ()

// 移动
// 返回迭代器节点偏移指定位置的那个节点
GSequenceIter * 	g_sequence_iter_move ()

// 比较
// 迭代器节点比较,两个节点需要在同一个序列
gint 	g_sequence_iter_compare ()

// 判断
// 节点是否为第一个迭代器节点
gboolean 	g_sequence_iter_is_begin ()
// 是否为最后一个迭代器节点
gboolean 	g_sequence_iter_is_end ()

// 获取值
// 根据序列节点获取节点的值
gpointer 	g_sequence_get ()

//设置值
// 修改一个序列节点的值,如果设置了数据销毁函数,则数据销毁函数会被调用,原数据会被销毁,内存自动回收
void 	g_sequence_set ()

// 搜索
GSequenceIter * 	g_sequence_search ()
GSequenceIter * 	g_sequence_search_iter ()

// 查找
// 给定查找函数查找节点,如果节点在序列中已经存在,可以使用lookup函数
// 如果序列中有多个相同的值,则lookup函数只会返回第一个值
// 如果序列未经排序,则查找失败
GSequenceIter * 	g_sequence_lookup ()
GSequenceIter * 	g_sequence_lookup_iter ()

// 排序
void 	g_sequence_sort_iter ()
void 	g_sequence_sort_changed_iter ()

// 信息获取
// 获取序列节点范围的一个中间节点。起始点需要在同一个序列中,并且起点需要比终点在序列中的位置靠前(位置相同也可以)
GSequenceIter * 	g_sequence_range_get_midpoint ()
// 获取序列的第一个迭代器节点
GSequenceIter * 	g_sequence_get_begin_iter ()
// 获取序列的最后一个迭代器节点
GSequenceIter * 	g_sequence_get_end_iter ()
// 给定位置返回迭代器节点
GSequenceIter * 	g_sequence_get_iter_at_pos ()
// 获取迭代器节点的位置
gint 	g_sequence_iter_get_position ()
// 返回迭代器节点所在的序列
GSequence * 	g_sequence_iter_get_sequence ()
演示程序:序列的创建-插入-删除-释放

源码见glib_examples\glib_sequence\glib_sequence_basic

#include <glib.h>

#define TEST_GLIB_SEQUENCE_NUM 5

typedef struct my_data_tag {
    gint id;
    gchar *name;
}my_data_t;


void _data_foreach_func(gpointer data, gpointer user_data)
{
    my_data_t *d = (my_data_t *)data;
    if(NULL != d) {
        g_print("(foreach)id:%d name:%s \n", d->id, d->name);
    }
}
void _data_destroy_func(gpointer data)
{
    my_data_t *d = (my_data_t *)data;
    g_return_if_fail(d);

    if(NULL != d->name) {
        g_print("(_data_destroy_func)id:%d name:%s \n", d->id, d->name);
        g_free(d->name);
    }
    g_free(d);
}

static void test_glib_sequence_basic(void)
{
    gint i;
    GSequence *seq = NULL;
    GSequenceIter *iter = NULL;
    my_data_t *d[TEST_GLIB_SEQUENCE_NUM];


    for(i=0;i<TEST_GLIB_SEQUENCE_NUM;i++) {
        d[i] = g_new0(my_data_t, 1);
        d[i]->id = i;
        d[i]->name = g_strdup_printf("name-%d", d[i]->id);
    }

    seq = g_sequence_new(_data_destroy_func);
    g_sequence_append(seq, (gpointer)d[2]);
    iter = g_sequence_append(seq, (gpointer)d[0]);
    g_sequence_insert_before(iter, (gpointer)d[3]);
    g_sequence_prepend(seq, (gpointer)d[1]);
    g_sequence_prepend(seq, (gpointer)d[4]);

    /* 4 1 2 3 0 */
    g_sequence_foreach(seq, _data_foreach_func, NULL);

    g_print("remove \n");
    g_sequence_remove(iter);

    g_print("free \n");
    g_sequence_free(seq);
}

gint main(gint argc, gchar **argv) 
{
    test_glib_sequence_basic();

    return 0;
}

运行结果:

[root@centos7_6 glib_sequence_basic]# ./glib_sequence_basic
(foreach)id:4 name:name-4
(foreach)id:1 name:name-1
(foreach)id:2 name:name-2
(foreach)id:3 name:name-3
(foreach)id:0 name:name-0
remove
(_data_destroy_func)id:0 name:name-0
free
(_data_destroy_func)id:1 name:name-1
(_data_destroy_func)id:3 name:name-3
(_data_destroy_func)id:2 name:name-2
(_data_destroy_func)id:4 name:name-4
演示程序:序列迭代器操作

源码见glib_examples\glib_sequence\glib_sequence_iter

#include <glib.h>

#define TEST_GLIB_SEQUENCE_NUM 5

typedef struct my_data_tag {
    gint id;
    gchar *name;
}my_data_t;

gint _sequence_iter_cmp_func(GSequenceIter *a, GSequenceIter *b, gpointer data)
{
    my_data_t *d1, *d2;
    d1 = g_sequence_get(a);
    d2 = g_sequence_get(b);

    g_return_if_fail(d1);
    g_return_if_fail(d2);

    g_print("(%s)a:%d, b:%d \n", (gchar *)data, d1->id, d2->id);

    return d1->id - d2->id;
}


void _data_foreach_func(gpointer data, gpointer user_data)
{
    my_data_t *d = (my_data_t *)data;
    if(NULL != d) {
        g_print("(foreach)id:%d name:%s \n", d->id, d->name);
    }
}
void _data_destroy_func(gpointer data)
{
    my_data_t *d = (my_data_t *)data;
    g_return_if_fail(d);

    if(NULL != d->name) {
        g_print("(_data_destroy_func)id:%d name:%s \n", d->id, d->name);
        g_free(d->name);
    }
    g_free(d);
}

static void test_glib_sequence_iter(void)
{
    gint i;
    GSequence *seq = NULL;
    GSequenceIter *iter = NULL;
    GSequenceIter *iter_begin, *iter_end;
    my_data_t *d[TEST_GLIB_SEQUENCE_NUM];
    my_data_t *tmp = NULL;


    for(i=0;i<TEST_GLIB_SEQUENCE_NUM;i++) {
        d[i] = g_new0(my_data_t, 1);
        d[i]->id = i;
        d[i]->name = g_strdup_printf("name-%d", d[i]->id);
    }

    seq = g_sequence_new(_data_destroy_func);
    g_sequence_append(seq, (gpointer)d[2]);
    iter = g_sequence_append(seq, (gpointer)d[0]);
    g_sequence_insert_before(iter, (gpointer)d[3]);
    g_sequence_prepend(seq, (gpointer)d[1]);
    g_sequence_prepend(seq, (gpointer)d[4]);

    /* 4 1 2 3 0 */
    g_print("foreach \n");
    g_sequence_foreach(seq, _data_foreach_func, NULL);

    g_print("iter \n");
    iter = g_sequence_get_begin_iter (seq);
    while (!g_sequence_iter_is_end (iter)) {
        tmp = g_sequence_get(iter);
        if(NULL != tmp) {
            g_print("(iter)id:%d name:%s \n", tmp->id, tmp->name);
        }
        iter = g_sequence_iter_next (iter);
    }

    g_print("free \n");
    g_sequence_free(seq);
}

gint main(gint argc, gchar **argv) 
{
    test_glib_sequence_iter();

    return 0;
}

运行结果:

[root@centos7_6 glib_sequence_iter]# ./glib_sequence_iter
foreach
(foreach)id:4 name:name-4
(foreach)id:1 name:name-1
(foreach)id:2 name:name-2
(foreach)id:3 name:name-3
(foreach)id:0 name:name-0
iter
(iter)id:4 name:name-4
(iter)id:1 name:name-1
(iter)id:2 name:name-2
(iter)id:3 name:name-3
(iter)id:0 name:name-0
free
(_data_destroy_func)id:4 name:name-4
(_data_destroy_func)id:1 name:name-1
(_data_destroy_func)id:3 name:name-3
(_data_destroy_func)id:2 name:name-2
(_data_destroy_func)id:0 name:name-0
演示程序:序列迭代器方式排序

源码见glib_examples\glib_sequence\glib_sequence_iter_sort

#include <glib.h>

#define TEST_GLIB_SEQUENCE_NUM 5

typedef struct my_data_tag {
    gint id;
    gchar *name;
}my_data_t;

gint _sequence_iter_cmp_func(GSequenceIter *a, GSequenceIter *b, gpointer data)
{
    my_data_t *d1, *d2;
    d1 = g_sequence_get(a);
    d2 = g_sequence_get(b);

    g_return_if_fail(d1);
    g_return_if_fail(d2);

    g_print("(%s)a:%d, b:%d \n", (gchar *)data, d1->id, d2->id);

    return d1->id - d2->id;
}


void _data_foreach_func(gpointer data, gpointer user_data)
{
    my_data_t *d = (my_data_t *)data;
    if(NULL != d) {
        g_print("(foreach)id:%d name:%s \n", d->id, d->name);
    }
}
void _data_destroy_func(gpointer data)
{
    my_data_t *d = (my_data_t *)data;
    g_return_if_fail(d);

    if(NULL != d->name) {
        g_print("(_data_destroy_func)id:%d name:%s \n", d->id, d->name);
        g_free(d->name);
    }
    g_free(d);
}

static void test_glib_sequence_iter_sort(void)
{
    gint i;
    GSequence *seq = NULL;
    GSequenceIter *iter = NULL;
    my_data_t *d[TEST_GLIB_SEQUENCE_NUM];


    for(i=0;i<TEST_GLIB_SEQUENCE_NUM;i++) {
        d[i] = g_new0(my_data_t, 1);
        d[i]->id = i;
        d[i]->name = g_strdup_printf("name-%d", d[i]->id);
    }

    seq = g_sequence_new(_data_destroy_func);
    g_sequence_append(seq, (gpointer)d[2]);
    iter = g_sequence_append(seq, (gpointer)d[0]);
    g_sequence_insert_before(iter, (gpointer)d[3]);
    g_sequence_prepend(seq, (gpointer)d[1]);
    g_sequence_prepend(seq, (gpointer)d[4]);

    /* 4 1 2 3 0 */
    g_print("foreach \n");
    g_sequence_foreach(seq, _data_foreach_func, NULL);

    g_print("sort iter \n");
    g_sequence_sort_iter(seq, _sequence_iter_cmp_func, (gpointer)"seq_iter_cmp");

    g_print("after sort iter, foreach \n");
    g_sequence_foreach(seq, _data_foreach_func, NULL);

    g_print("free \n");
    g_sequence_free(seq);
}

gint main(int gargc, gchar **argv) 
{
    test_glib_sequence_iter_sort();

    return 0;
}

运行结果:

[root@centos7_6 glib_sequence_iter_sort]# ./glib_sequence_iter_sort
foreach
(foreach)id:4 name:name-4
(foreach)id:1 name:name-1
(foreach)id:2 name:name-2
(foreach)id:3 name:name-3
(foreach)id:0 name:name-0
sort iter
(seq_iter_cmp)a:4, b:1
(seq_iter_cmp)a:4, b:2
(seq_iter_cmp)a:1, b:2
(seq_iter_cmp)a:4, b:3
(seq_iter_cmp)a:1, b:3
(seq_iter_cmp)a:2, b:3
(seq_iter_cmp)a:4, b:0
(seq_iter_cmp)a:1, b:0
after sort iter, foreach
(foreach)id:0 name:name-0
(foreach)id:1 name:name-1
(foreach)id:2 name:name-2
(foreach)id:3 name:name-3
(foreach)id:4 name:name-4
free
(_data_destroy_func)id:2 name:name-2
(_data_destroy_func)id:3 name:name-3
(_data_destroy_func)id:1 name:name-1
(_data_destroy_func)id:0 name:name-0
(_data_destroy_func)id:4 name:name-4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值