1 队列的基本概念

alt text

网上大部分队列是尾部入队,头部出队,使用单链表进行实现。GLib使用双向链表实现,可以两头入队,两头出队。

2 GQueue

  1. GQueue 没有在类型系统注册对象,也就是没有 G_QUEUE,没有引用计数。

  2. g_queue_new 创建队列,g_queue_free 释放队列内存空间。

  3. GQueue 不是多线程安全的。

2.1 GQueue结构体

typedef struct _GQueue GQueue;
struct _GQueue
{
  GList *head; /* 指向队列的第一个元素 */
  GList *tail; /* 指向队列的最后一个元素 */
  guint  length; /* 队列元素个数 */
};

2.2 函数总结

2.2.1 队列创建

(1)队列创建和释放

GQueue*  g_queue_new            (void);
void     g_queue_free           (GQueue           *queue);

(2)队列的初始化和清理

/**
 * @brief: 我认为这是初始化局部变量或者全局变量队列。
*/
void
g_queue_init (GQueue *queue) {
  g_return_if_fail (queue != NULL);

  queue->head = queue->tail = NULL;
  queue->length = 0;
}

/**
 * @brief: 我认为这是释放局部变量或者全局变量队列。
*/
void
g_queue_clear (GQueue *queue)
{
  g_return_if_fail (queue != NULL);

  g_list_free (queue->head);
  g_queue_init (queue);
}

2.2.2 队列压入数据

(1)队列头部压入

void     g_queue_push_head      (GQueue           *queue,
                                 gpointer          data);

(2)队列尾部压入

void     g_queue_push_tail      (GQueue           *queue,
                                 gpointer          data);

(3)队列根据位置number压入

void     g_queue_push_nth       (GQueue           *queue,
                                 gpointer          data,
                                 gint              n);

(4) 队列根据节点地址在前面压入

void     g_queue_insert_before  (GQueue           *queue,
                                 GList            *sibling,
                                 gpointer          data);

(5)队列根据节点地址在后面压入

GLIB_AVAILABLE_IN_ALL
void     g_queue_insert_after   (GQueue           *queue,
                                 GList            *sibling,
                                 gpointer          data);

(6)队列根据用户自定义排序函数在前面压入

void     g_queue_insert_sorted  (GQueue           *queue,
                                 gpointer          data,
                                 GCompareDataFunc  func,
                                 gpointer          user_data);

2.2.3 取出data同时删除在队列中删除

(1)取出头节点data

gpointer g_queue_pop_head       (GQueue           *queue);

(2)取出尾节点data

gpointer g_queue_pop_tail       (GQueue           *queue);

(2)根据位置取出头节点data

gpointer g_queue_pop_nth        (GQueue           *queue,
                                 guint             n);

2.2.4 只查看data不删除

(1)头节点

gpointer g_queue_peek_head      (GQueue           *queue);

(2)尾节点

gpointer g_queue_peek_tail      (GQueue           *queue);

(3)根据位置查询节点

gpointer g_queue_peek_nth       (GQueue           *queue,
                                 guint             n);

2.2.5只查询Glist不删除

(1)根据data查询

GList *  g_queue_find           (GQueue           *queue,
                                 gconstpointer     data);

(2)根据用户定义func查询

GList *  g_queue_find_custom    (GQueue           *queue,
                                 gconstpointer     data,
                                 GCompareFunc      func);

2.2.6根据data删除队列

(1)只删除第一个相同data

gboolean g_queue_remove         (GQueue           *queue,
                                 gconstpointer     data);

(2)删除所有相同data

guint    g_queue_remove_all     (GQueue           *queue,
                                 gconstpointer     data);

2.2.7 反转队列

void     g_queue_reverse        (GQueue           *queue);

2.2.8 判断队列是否为空

gboolean g_queue_is_empty       (GQueue           *queue);

参考

参考:数据结构 —— 队列(超详细图解 & 接口函数实现)