目錄
一、隊列基礎知識
在上一篇的順序隊列中已經講解過了隊列的基礎知識,這篇主要來講一下隊列的另一種結構 --- 鏈式隊列,本文使用的鏈表結構爲單向鏈表。同樣使用兩個指針:
head指針指向隊頭,跟順序隊列一樣指向將要出隊的節點,出隊過程爲:取出head指向節點的數據,再將head指向下一個節點
tail指針指向隊尾;跟順序隊列有點不同,順序隊列tail指向即將入隊的節點,入隊過程爲:將數據存放到tail指向的節點中,再將tail指向下一個將要入隊的位置;而鏈式隊列中tail指向最後一次入隊的節點,入隊過程爲:將數據存放到tail指向節點的下一節點中,再將tail指向剛添加的節點
二、鏈式隊列數據結構
#define LIST_QUEUE_NUM(pqueue) (pqueue->num)
#define LIST_QUEUE_IS_EMPTY(pqueue) (pqueue->num == 0)
struct list_queue_node
{
struct list_queue_node *next; /* next node*/
int value_size; /* value size */
void *value; /* node value */
};
struct list_queue
{
struct list_queue_node *head; /* points to the the next dequeue data */
struct list_queue_node *tail; /* points to the the last enqueue data */
int num; /* queue node num */
};
三、鏈式隊列操作函數聲明
extern struct list_queue* list_queue_creat(void);
extern int list_queue_init (struct list_queue *queue);
extern int list_queue_empty (struct list_queue *queue);
extern int list_queue_destory(struct list_queue *queue);
extern int list_queue_dequeue(struct list_queue *queue, void *out_data);
extern int list_queue_enqueue(struct list_queue *queue, void *in_data, int dsize);
extern void list_queue_test(void);
四、創建鏈式隊列
1、隊列頭部動態創建
/**
* dynamically create a list queue.
*
* @return NULL:malloc fail
* !NULL:success
*/
struct list_queue* list_queue_creat(void)
{
struct list_queue *queue = NULL;
queue = LIST_QUEUE_CALLOC(1,sizeof(*queue));
if (queue == NULL)
return NULL;
queue->head = NULL;
queue->tail = NULL;
queue->num = 0;
return queue;
}
2、隊列頭部靜態創建
/**
* init a list queue.
*
* @param queue:list queue
* @return -1:queue is null
* 0:success
*/
int list_queue_init(struct list_queue *queue)
{
if (queue == NULL)
return -1;
queue->head = NULL;
queue->tail = NULL;
queue->num = 0;
return 0;
}
五、出隊列
/**
* dequeue data from the list queue.
*
* @param queue: list queue
* @param out_data: dequeue data
* @return -1: fail
* -2: queue is empty
* 0: success
*/
int list_queue_dequeue(struct list_queue *queue, void *out_data)
{
struct list_queue_node *del_node = NULL;
if (queue == NULL)
return -1;
if (LIST_QUEUE_IS_EMPTY(queue))
return -2;
del_node = queue->head;
queue->head = del_node->next;
queue->num--;
memcpy(out_data, del_node->value, del_node->value_size);
LIST_QUEUE_FREE(del_node->value);
LIST_QUEUE_FREE(del_node);
del_node->value = NULL;
del_node = NULL;
return 0;
}
六、入隊列
/**
* enqueue data to the list queue backwards.
*
* @param queue: list queue
* @param in_data: enqueue data
* @return -1: fail
* 0: success
*/
int list_queue_enqueue(struct list_queue *queue, void *in_data, int dsize)
{
struct list_queue_node *add_node = NULL;
if (queue == NULL)
return -1;
/* malloc add_node space */
add_node = LIST_QUEUE_MALLOC(sizeof(*add_node));
if (add_node == NULL)
return -1;
/* malloc value space */
add_node->value = LIST_QUEUE_MALLOC(dsize);
if (add_node->value == NULL)
return -1;
memcpy(add_node->value, in_data, dsize);
add_node->value_size = dsize;
add_node->next = NULL;
if (queue->head == NULL )
{
queue->head = add_node;
queue->tail = add_node;
}
else
{
queue->tail->next = add_node;
queue->tail = add_node;
}
queue->num++;
return 0;
}
七、隊列刪除
/**
* delete list queue space.
*
* @param queue: list queue
* @return -1: fail
* 0:success
*/
int list_queue_empty(struct list_queue *queue)
{
struct list_queue_node *del_node = NULL;
if (queue == NULL)
return -1;
while (!LIST_QUEUE_IS_EMPTY(queue))
{
del_node = queue->head;
queue->head = del_node->next;
queue->num--;
LIST_QUEUE_FREE(del_node->value);
del_node->value = NULL;
LIST_QUEUE_FREE(del_node);
del_node = NULL;
}
return 0;
}
八、隊列銷燬
/**
* delete and destroy a list queue.
*
* @param queue: list queue
* @return -1: fail
* 0:success
*/
int list_queue_destory(struct list_queue *queue)
{
if (list_queue_empty(queue) != 0)
return -1;
LIST_QUEUE_FREE(queue);
queue = NULL;
return 0;
}
九、驗證程序
struct list_queue *list_queue_head;
int list_queue_w[5] = {11,22,33,44,55};
int list_queue_r[5] = {0};
void list_queue_test(void)
{
list_queue_head = list_queue_creat();
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[0], 4);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[1], 4);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[2], 4);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[3], 4);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[4], 4);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[0]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[1]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[2]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[3]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[4]);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[2], 4);
list_queue_enqueue(list_queue_head, (void*)&list_queue_w[2], 4);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[0]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[1]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[2]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[3]);
list_queue_dequeue(list_queue_head, (void*)&list_queue_r[4]);
}