数据结构 --- 链式队列(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]);
}

发布了35 篇原创文章 · 获赞 22 · 访问量 1145

猜你喜欢

转载自blog.csdn.net/m0_37845735/article/details/103330822