Glib学习(18) 基于二叉树的队列 Sequences

glib源码下载:http://ftp.gnome.org/pub/gnome/sources/glib/

glib帮助文档:https://developer.gnome.org/glib/

本节主要讲解一下Sequences-序列,这个序列的实现是基于二叉树,所以在查找的效率上是非常高的,而且有非常丰富的基于迭代器的函数。

我把函数使用谷歌翻译了一下,没有仔细校验,因为英语是在太差,而且函数基本差不多,懂了一个就能举一反三。

迭代器在c++中是非常基础的api,所以我也不打算在这里讲解太多,我就简单的使用了几个基本的函数,剩下的就和c++差不多了。

Includes
#include <gmodule.h>

描述
GSequence数据结构具有列表的API,但在内部使用平衡二叉树实现。 这意味着可以在时间O(n log n)中维护一个有n个元素的排序列表。 包含在每个元素中的数据可以是整型值,也可以是Type Conversion Macros,或者是指向任何类型数据的指针。
一个GSequence通过一个由GSequenceIter表示的“迭代器”来访问。 迭代器表示序列中两个元素之间的位置。 例如,迭代器的“begin”代表在序列的第一个元素,迭代器的“end”代表在最后一个元素。 在一个空序列中,“begin”和“end”迭代器是相同的。
GSequence上的一些方法对范围进行操作。 例如,g_sequence_foreach_range()将在给定范围的每个元素上调用用户指定的函数。 范围由传入的迭代器表示的间隙分隔,所以如果您传入开始和结束迭代器,那么所遍历的范围就是整个序列。
函数g_sequence_get()与迭代器一起用于访问紧跟在迭代器表示的间隙之后的元素。 迭代器被称为“指向”该元素。
迭代器在GSequence的大多数操作中都很稳定。 例如,指向序列某个元素的迭代器即使在序列被排序后也会继续指向该元素。 即使使用例如g_sequence_move_range()将元素移动到另一个序列,也不会使指向它的迭代器无效。 唯一会使迭代器无效的操作是当它指向的元素从任何序列中移除时。


函数
gint (*GSequenceIterCompareFunc) ()
GSequenceIterCompareFunc是一个用来比较迭代器的函数。 如果迭代器比较相等,则它必须返回零,如果a出现在b之前,则返回负值,如果b出现在a之前,则返回正值。
参数
a
一个GSequenceIter
b
一个GSequenceIter
data
用户数据
返回
如果迭代器相等,则为零;如果a在b之前,则为负值,如果b在a之前,则为正值。

GSequence * g_sequence_new ()
创建一个新的GSequence。 data_destroy函数(如果为非NULL)将在序列销毁时在所有项目上以及从序列中删除的项目上调用。
参数
data_destroy
GDestroyNotify函数或NULL。
返回
一个新的GSequence。

void g_sequence_free ()
释放为seq分配的内存。 如果seq具有与之关联的数据销毁功能,则在seq中的所有项目上调用该函数。
参数
seq
一个GSequence

gint g_sequence_get_length ()
返回seq的长度。 注意这个方法是O(h),其中‘h’是树的高度。 因此,在将长度与零比较时使用g_sequence_is_empty()会更有效。
参数
seq
一个GSequence
返回
seq的长度

gboolean g_sequence_is_empty ()
如果序列包含零个项目,则返回TRUE。
该函数在功能上与检查g_sequence_get_length()的结果等于零相同。 然而这个功能是在O(1)运行时间内实现的。
参数
seq
一个GSequence
返回
如果序列为空则为TRUE,否则为FALSE。

void g_sequence_foreach ()
为顺序中的每个项目调用func,将user_data传递给该函数。 func不能修改序列本身。
参数
seq
一个GSequence
func
调用seq中的每个项目的函数
user_data
用户数据传递给func

void g_sequence_foreach_range ()
为范围(开始,结束)中的每个项目调用func将user_data传递给该函数。 func不能修改序列本身。
参数
begin
一个GSequenceIter
end
一个GSequenceIter
func
GFunc
user_data
用户数据传递给func

void g_sequence_sort ()
使用cmp_func对seq进行排序。
cmp_func传递两个seq,如果它们相等,则返回0;如果第一个出现在第二个之前,则返回负值;如果第二个出现在第一个之前,则返回正值。
参数
seq
一个GSequence
cmp_func
用于对序列进行排序的函数
cmp_data
用户数据传递给cmp_func

void g_sequence_sort_iter ()
像g_sequence_sort()一样,但使用GSequenceIterCompareFunc而不是GCompareDataFunc作为比较函数
用两个指向seq的迭代器调用cmp_func。 如果迭代器相等,它应该返回0,如果第一个迭代器在第二个迭代器之前出现则返回负值,如果第二个迭代器在第一个迭代器之前出现则返回正值。
参数
seq
一个GSequence
cmp_func
该函数用于比较序列中的迭代器
cmp_data
用户数据传递给cmp_func

GSequenceIter * g_sequence_get_begin_iter ()
返回seq的开始迭代器。
参数
seq
一个GSequence
返回
seq的开始迭代器。

GSequenceIter * g_sequence_get_end_iter ()
返回seq的结束迭代器
参数
seq
一个GSequence
返回
seq的结束迭代器。

GSequenceIter * g_sequence_get_iter_at_pos ()
返回迭代器pos处的位置。如果pos为负数或大于seq中的项数,则返回end迭代器。
参数
seq
一个GSequence
pos
seq中的一个位置,或者最后的-1
返回
GSequenceIter在位置pos。

GSequenceIter * g_sequence_append ()
在seq结尾添加一个新项目。
参数
seq
一个GSequence
data
新项目的数据
返回
指向新项目的迭代器。

GSequenceIter * g_sequence_prepend ()
向seq的前面添加一个新项目
参数
seq
一个GSequence
data
新项目的数据
返回
指向新项目的迭代器。

GSequenceIter * g_sequence_insert_before ()
在iter指向的项目之前插入一个新项目。
参数
iter
一个GSequenceIter
data
新项目的数据
返回
指向新项目的迭代器。

void g_sequence_move ()
将src指向的项移动到dest指定的位置。 调用此函数后,dest将指向src后立即的位置。 允许src和dest指向不同的序列。
参数
src
指向要移动的项目的GSequenceIter
dest
一个指向项目移动位置的GSequenceIter

void g_sequence_swap ()
交换a和b指向的项目。 允许a和b指向不同的序列。
参数
a
一个GSequenceIter
b
一个GSequenceIter

GSequenceIter * g_sequence_insert_sorted ()
使用func将数据插入到序列中以确定新的位置。 序列必须已经按照cmp_func; 否则数据的新位置是未定义的。
使用seq和user_data两项调用cmp_func。 如果项目相等,它应该返回0,如果第一个项目在第二个项目之前出现则返回负值,如果第二个项目在第一个项目之前出现则返回正值。
参数
seq
一个GSequence
data
要插入的数据
cmp_func
该函数用于比较序列中的项目
cmp_data
用户数据传递给cmp_func。
返回
指向新项目的GSequenceIter。

GSequenceIter * g_sequence_insert_sorted_iter ()
像g_sequence_insert_sorted()一样,但使用GSequenceIterCompareFunc而不是GCompareDataFunc作为比较函数。
iter_cmp被两个指向seq的迭代器调用。 如果迭代器相等,它应该返回0,如果第一个迭代器在第二个迭代器之前出现则返回负值,如果第二个迭代器在第一个迭代器之前出现则返回正值。
它被两个指向seq的迭代器调用。 如果迭代器相等,它应该返回0,如果第一个迭代器在第二个迭代器之前出现则返回负值,如果第二个迭代器在第一个迭代器之前出现则返回正值。
参数
seq
一个GSequence
data
新项目的数据
iter_cmp
该函数用于比较序列中的迭代器
cmp_data
用户数据传递给cmp_func
返回
指向新项目的GSequenceIter。

void g_sequence_sort_changed ()
将指向新位置的数据移动,如cmp_func所示。 只要项目的某个方面发生更改,就可以调用已按照cmp_func排序的项目中的项目,以便cmp_func可以为该项目返回不同的值。
使用seq和user_data两项调用cmp_func。 如果项目相等,它应该返回0,如果第一个项目在第二个项目之前出现则返回负值,如果第二个项目在第一个项目之前出现则返回正值。
参数
iter
一个GSequenceIter
cmp_func
该函数用于比较序列中的项目
cmp_data
用户数据传递给cmp_func。

void g_sequence_sort_changed_iter ()
像g_sequence_sort_changed()一样,但使用GSequenceIterCompareFunc而不是GCompareDataFunc作为比较函数。
iter_cmp被两个指向seq的迭代器调用。 如果迭代器相等,它应该返回0,如果第一个迭代器在第二个迭代器之前出现则返回负值,如果第二个迭代器在第一个迭代器之前出现则返回正值。
参数
iter
一个GSequenceIter
iter_cmp
该函数用于比较序列中的迭代器
cmp_data
用户数据传递给cmp_func

void g_sequence_remove ()
删除iter指向的项目。 将结束迭代器传递给此函数是错误的。
如果序列具有与之关联的数据销毁功能,则会在已删除项目的数据上调用此函数。
参数
iter
一个GSequenceIter

void g_sequence_remove_range ()
删除(开始,结束)范围内的所有项目。
如果序列具有与之关联的数据销毁功能,则会在已删除项目的数据上调用此函数。
参数
begin
一个GSequenceIter
end
一个GSequenceIter

void g_sequence_move_range ()
在ptr指向的目标处插入(开始,结束)范围。 开始和结束iters必须指向相同的序列。 允许dest指向与开始和结束指向的序列不同的序列。
如果dest为NULL,则从序列中删除由begin和end指示的范围。 如果目标指向(开始,结束)范围内的某个位置,则范围不会移动。
参数
dest
一个GSequenceIter
begin
一个GSequenceIter
end
一个GSequenceIter

GSequenceIter * g_sequence_search ()
根据cmp_func和cmp_data返回一个指向数据插入迭代器的位置。
使用seq和user_data两项调用cmp_func。如果项目相等,它应该返回0,如果第一个项目在第二个项目之前出现则返回负值,如果第二个项目在第一个项目之前出现则返回正值。
如果您只是在搜索序列的现有元素,请考虑使用g_sequence_lookup()。
如果序列中包含的数据未排序,则此功能将失败。使用g_sequence_insert_sorted()或g_sequence_insert_sorted_iter()将数据添加到序列中,或者如果要添加大量数据,请在执行未排序的插入操作后调用g_sequence_sort()。
参数
seq
一个GSequence
data
新项目的数据
cmp_func
该函数用于比较序列中的项目
cmp_data
用户数据传递给cmp_func
返回
一个GSequenceIter指向根据cmp_func和cmp_data插入数据的位置。

GSequenceIter * g_sequence_search_iter ()
与g_sequence_search()类似,但使用GSequenceIterCompareFunc而不是GCompareDataFunc作为比较函数。
iter_cmp被两个指向seq的迭代器调用。如果迭代器相等,它应该返回0,如果第一个迭代器出现在第二个迭代器之前,则返回负值,如果第二个迭代器出现在第一个迭代器之前,则返回正值。
如果您只是在搜索序列的现有元素,请考虑使用g_sequence_lookup_iter()。
如果序列中包含的数据未排序,则此功能将失败。使用g_sequence_insert_sorted()或g_sequence_insert_sorted_iter()将数据添加到序列中,或者如果要添加大量数据,请在执行未排序的插入操作后调用g_sequence_sort()。
参数
seq
一个GSequence
data
新项目的数据
iter_cmp
该函数用于比较序列中的迭代器
cmp_data
用户数据传递给iter_cmp
返回
一个GSequenceIter指向seq中根据iter_cmp和cmp_data插入数据的位置。

GSequenceIter * g_sequence_lookup ()
根据cmp_func和cmp_data返回一个指向第一个找到的数据位置的迭代器。如果多个项目相同,则不能保证它是第一个返回的项目。在这种情况下,您可以使用g_sequence_iter_next()和g_sequence_iter_prev()来获取其他人。
使用seq和user_data两项调用cmp_func。如果项目相等,它应该返回0,如果第一个项目在第二个项目之前出现则返回负值,如果第二个项目在第一个项目之前出现则返回正值。
如果序列中包含的数据未排序,则此功能将失败。使用g_sequence_insert_sorted()或g_sequence_insert_sorted_iter()将数据添加到序列中,或者如果要添加大量数据,请在执行未排序的插入操作后调用g_sequence_sort()。
参数
seq
一个GSequence
data
要查找的数据
cmp_func
该函数用于比较序列中的项目
cmp_data
用户数据传递给cmp_func
返回
一个GSequenceIter指向根据cmp_func和cmp_data发现的第一个项目的位置等于数据,如果不存在这样的项目,则为NULL。

GSequenceIter * g_sequence_lookup_iter ()
像g_sequence_lookup()一样,但使用GSequenceIterCompareFunc而不是GCompareDataFunc作为比较函数。
iter_cmp被两个指向seq的迭代器调用。 如果迭代器相等,它应该返回0,如果第一个迭代器在第二个迭代器之前出现则返回负值,如果第二个迭代器在第一个迭代器之前出现则返回正值。
如果序列中包含的数据未排序,则此功能将失败。 使用g_sequence_insert_sorted()或g_sequence_insert_sorted_iter()将数据添加到序列中,或者如果要添加大量数据,请在执行未排序的插入操作后调用g_sequence_sort()。
参数
seq
一个GSequence
data
要查找的数据
iter_cmp
该函数用于比较序列中的迭代器
cmp_data
用户数据传递给iter_cmp
返回
一个GSequenceIter指向根据cmp_func和cmp_data发现的第一个项目的位置等于数据,或者如果不存在这样的项目,则为NULL。

gpointer g_sequence_get ()
返回iter指向的数据。
参数
iter
一个GSequenceIter
返回
iter指向的数据。

void g_sequence_set ()
将由iter指向的项目的数据更改为数据。 如果该序列具有与之关联的数据销毁功能,则该函数将在所指向的现有数据上调用。
参数
iter
一个GSequenceIter
data
该项目的新数据

gboolean g_sequence_iter_is_begin ()
返回iter是否是开始迭代器
参数
iter
一个GSequenceIter
返回
是否是开始迭代器

gboolean g_sequence_iter_is_end ()
返回iter是否是结束迭代器
参数
iter
一个GSequenceIter
返回
它是否是最终迭代器

GSequenceIter * g_sequence_iter_next ()
返回指向iter后面的下一个位置的迭代器。 如果iter是结束迭代器,则返回结束迭代器。
参数
iter
一个GSequenceIter
返回
一个GSequenceIter指向之后的下一个位置。

GSequenceIter * g_sequence_iter_prev ()
返回指向iter之前的前一个位置的迭代器。 如果iter是开始迭代器,则返回开始迭代器。
参数
iter
一个GSequenceIter
返回
一个GSequenceIter指向之前的位置。

gint g_sequence_iter_get_position ()
返回iter的位置
参数
iter
一个GSequenceIter
返回
iter的位置

GSequenceIter * g_sequence_iter_move ()
返回距离iter的delta位置的GSequenceIter。 如果iter比-delta位置更接近序列的开始位置,则返回begin迭代器。 如果iter比delta位置更接近序列末尾,则返回结束迭代器。
参数
iter
一个GSequenceIter
delta
一个正数或负数表示距离返回的GSequenceIter有多少个位置
返回
一个GSequenceIter是三角洲位置远离iter。

GSequence * g_sequence_iter_get_sequence ()
返回iter指向的GSequence。
参数
iter
一个GSequenceIter
返回
iter指向的GSequence。

gint g_sequence_iter_compare ()
如果a在b之前,则返回负数;如果b相等,则返回0;如果a在b之后,则返回正数。
a和b迭代器必须指向相同的序列。
参数
a
一个GSequenceIter
b
一个GSequenceIter
返回
如果a在b之前,则为负数,如果相等则为0,如果a在b之后,则为正数

GSequenceIter * g_sequence_range_get_midpoint ()
在范围内的某处(开始,结束)查找迭代器。 这个迭代器将接近范围的中间,但不能保证完全在中间。
开始和结束迭代器都必须指向相同的序列,并且开始必须在序列之前或等于结束。
参数
begin
一个GSequenceIter
end
一个GSequenceIter
返回
一个GSequenceIter指向(开始,结束)范围内的某处。

类型和值
GSequence
GSequence结构是表示序列数据类型,不公开数据类型。
GSequenceIter
GSequenceIter结构是一个不公开的数据类型,代表指向GSequence的迭代器。


例程

#include <gmodule.h>
#include <glib.h>
#include <glib/gprintf.h>

void seqPrintf (gpointer data, gpointer user_data)
{
	g_printf ("data is %d\n", GPOINTER_TO_INT(data));
}

gint CompareDataFunc (gconstpointer a, gconstpointer b, gpointer user_data)
{
	return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
}

gint SequenceIterCompareFunc (GSequenceIter *a, GSequenceIter *b, gpointer data)
{//反序
	return GPOINTER_TO_INT(g_sequence_get (b)) - GPOINTER_TO_INT(g_sequence_get (a));
}

int main(int argc, char **argv)
{
	g_printf ("main in\n");

	GSequence *seq =
	g_sequence_new (NULL);

	g_printf ("sequence get length is %d\n", g_sequence_get_length (seq));
	g_sequence_is_empty(seq) ? g_printf ("sequence is empty\n") : g_printf ("sequence is not empty\n");

	int i;
	for(i=0; i<10;i++)
		g_sequence_append (seq, GINT_TO_POINTER(i));
	
	for(i=10; i<20;i++)
		g_sequence_prepend (seq, GINT_TO_POINTER(i));
	
	g_printf ("sequence append&prepend\n");
	g_sequence_foreach (seq, seqPrintf, NULL);
	
	g_sequence_sort (seq, CompareDataFunc, NULL);
	g_printf ("sequence sort\n");
	g_sequence_foreach (seq, seqPrintf, NULL);
	
	g_sequence_sort_iter (seq, SequenceIterCompareFunc, NULL);
	g_printf ("sequence sort iter\n");
	g_sequence_foreach (seq, seqPrintf, NULL);
	
	g_sequence_free (seq);

	g_printf ("main out\n");
    return 0;
}


猜你喜欢

转载自blog.csdn.net/andylauren/article/details/80150699