简介
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