數據結構 --- 鏈式隊列(C語言實現)

目錄

一、隊列基礎知識

二、鏈式隊列數據結構

三、鏈式隊列操作函數聲明

四、創建鏈式隊列

1、隊列頭部動態創建

2、隊列頭部靜態創建

五、出隊列

六、入隊列

七、隊列刪除

八、隊列銷燬

九、驗證程序


一、隊列基礎知識

在上一篇的順序隊列中已經講解過了隊列的基礎知識,這篇主要來講一下隊列的另一種結構 --- 鏈式隊列,本文使用的鏈表結構爲單向鏈表。同樣使用兩個指針:

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]);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章