C语言队列操作接口实现

下面是队列接口实现代码 有疑问可以讨论

队列接口实现文件

queue_api.c

/*********************************************************************
 * 版权所有 (c) 2021-2022  axk. 保留所有版权
 * 文件名称: queue_api.c
 * 文件描述: 标准队列操作接口实现
 * 作    者: axk
 * 创建日期: 2022/11/23
 * 作    者                 日    期                 版    本          修改摘要
 * axk                   2022/11/23               1.0           文件创建
**********************************************************************/


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include "axk_base_data_type.h"
#include "queue_api.h"

/***********************************************************************
 * 函数名称: queue_node_free
 * 功能描述: 释放队列节点内存
 * 输    入:node 需要释放的节点
 * 输    出: 无
 * 返 回 值: void
 * 其    他:
 * 日    期: 2022/11/21
 * 作    者: axk
 ***********************************************************************/
void queue_node_free(queue_node_s_type* node)
{
    
    
    if (NULL != node)
    {
    
    
        if (NULL != node->data)
        {
    
    
            if (NULL != node->free_cb)
            {
    
    
                node->free_cb(node->data);
            }
        }
        node->next = NULL;
        node->prev = NULL;
        free(node);
        node = NULL;
    }
}

/***********************************************************************
 * 函数名称: queue_push
 * 功能描述: 入队一个节点
 * 输    入:queue_head 队列头
 *         data 节点数据内容
 *         free_cb 节点数据free函数 (如果节点释放不需要free数据则填空)
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_push(queue_head_s_type* queue_head, void* data, queue_data_free_cb free_cb)
{
    
    
    queue_node_s_type* data_node = NULL;
    queue_node_s_type* tmp_node = NULL;

    if (NULL == queue_head || NULL == data)
    {
    
    
        AXK_LOGE("queue_head or data is NULL!");
        return AXK_ERR_PARAMETER;
    }

    data_node = (queue_node_s_type*)malloc(sizeof(queue_node_s_type));
    if (NULL == data_node)
    {
    
    
        AXK_LOGE("data_node malloc failed!");
        return AXK_ERR_MALLOC;
    }
    memset(data_node, 0x0, sizeof(queue_node_s_type));
    data_node->next = NULL;
    data_node->prev = NULL;
    data_node->data = data;
    data_node->free_cb = free_cb;

    if (NULL != queue_head->tail)
    {
    
    
        queue_head->tail->next = data_node;
        data_node->prev = queue_head->tail;
        queue_head->tail = data_node;
    }
    else
    {
    
    
        queue_head->head = data_node;
        queue_head->tail = data_node;
    }
    queue_head->node_num++;

    return AXK_SUCCESS;
}

/***********************************************************************
 * 函数名称: queue_pop
 * 功能描述: 出队一个节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回节点地址(需要外部释放,节点数据内存也需要释放)
             失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_pop(queue_head_s_type* queue_head)
{
    
    
    queue_node_s_type* tmp_node = NULL;
    if (NULL == queue_head)
    {
    
    
        AXK_LOGE("queue_head is NULL!");
        return NULL;
    }

    if (NULL == queue_head->head)
    {
    
    
        AXK_LOGE("queue_head is empty!");
        return NULL;
    }

    tmp_node = queue_head->head;
    if (NULL != tmp_node->next)
    {
    
    
        queue_head->head = tmp_node->next;
        queue_head->head->prev = NULL;
    }
    else
    {
    
    
        queue_head->tail = NULL;
        queue_head->head = NULL;
    }
    queue_head->node_num--;

    return tmp_node;
}

/***********************************************************************
 * 函数名称: queue_get_head_node
 * 功能描述: 获取队列头部数据节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回头节点指针 失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_get_head_node(queue_head_s_type* queue_head)
{
    
    
    if (NULL == queue_head)
    {
    
    
        AXK_LOGE("queue_head is NULL!");
        return NULL;
    }

    return queue_head->head;
}

/***********************************************************************
 * 函数名称: queue_get_tail_node
 * 功能描述: 获取队列尾部数据节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回尾部节点指针 失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_get_tail_node(queue_head_s_type* queue_head)
{
    
    
    if (NULL == queue_head)
    {
    
    
        AXK_LOGE("queue_head is NULL!");
        return NULL;
    }

    return queue_head->tail;
}

/***********************************************************************
 * 函数名称: queue_destory
 * 功能描述: 队列销毁
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_destory(queue_head_s_type* queue_head)
{
    
    
    queue_node_s_type* tmp_node = NULL;
    if (NULL == queue_head)
    {
    
    
        AXK_LOGE("queue_head is NULL!");
        return AXK_ERR_PARAMETER;
    }

    while (0 != queue_head->node_num)
    {
    
    
        tmp_node = queue_head->tail;
        if (NULL != tmp_node->prev)
        {
    
    
            queue_head->tail = tmp_node->prev;
            queue_head->tail->next = NULL;
        }
        else
        {
    
    
            queue_head->tail = NULL;
            queue_head->head = NULL;
        }
        queue_node_free(tmp_node);
        queue_head->node_num--;
    }

    return AXK_SUCCESS;
}

/***********************************************************************
 * 函数名称: queue_init
 * 功能描述: 队列初始化
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_init(queue_head_s_type* queue_head)
{
    
    
    if (NULL == queue_head)
    {
    
    
        AXK_LOGE("queue_head is NULL!");
        return AXK_ERR_PARAMETER;
    }
    queue_destory(queue_head);

    queue_head->node_num = 0;
    queue_head->head = NULL;
    queue_head->tail = NULL;
    return AXK_SUCCESS;
}

队列接口头文件

/*********************************************************************
 * 版权所有 (h) 2021-2022  axk. 保留所有版权
 * 文件名称: queue_api.h
 * 文件描述: 标准队列操作接口头文件
 * 作    者: axk
 * 创建日期: 2022/11/23
 * 作    者                 日    期                 版    本          修改摘要
 * axk                   2022/11/23               1.0           文件创建
**********************************************************************/
#ifndef __QUEUE_API_H_
#define __QUEUE_API_H_

#include "axk_base_data_type.h"

#ifdef __cplusplus
extern "C" {
    
    
#endif

/****************************QUEUE_API 宏定义 start****************************************************/
/****************************QUEUE_API 宏定义 end****************************************************/

/****************************QUEUE_API 枚举定义 start****************************************************/

/****************************QUEUE_API 枚举定义 end****************************************************/

/****************************QUEUE_API 结构体定义 start****************************************************/
/* 释放节点数据回调函数 */
typedef void (*queue_data_free_cb)(void* data);

/* 队列节点结构体 */
typedef struct queue_node_s_type
{
    
    
    struct queue_node_s_type* next;
    struct queue_node_s_type* prev;
    void* data;
    queue_data_free_cb free_cb;
} queue_node_s_type;

/* 队列头结构体 */
typedef struct queue_head_s_type
{
    
    
    int node_num;
    struct queue_node_s_type* head;
    struct queue_node_s_type* tail;
} queue_head_s_type;
/****************************QUEUE_API 结构体定义 end****************************************************/

/****************************QUEUE_API 函数声明 start****************************************************/
/***********************************************************************
 * 函数名称: queue_push
 * 功能描述: 入队一个节点
 * 输    入:queue_head 队列头
 *         data 节点数据内容
 *         free_cb 节点数据free函数 (如果节点释放不需要free数据则填空)
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_push(queue_head_s_type* queue_head, void* data, queue_data_free_cb free_cb);

/***********************************************************************
 * 函数名称: queue_pop
 * 功能描述: 出队一个节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回节点地址(需要外部释放,节点数据内存也需要释放)
             失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_pop(queue_head_s_type* queue_head);

/***********************************************************************
 * 函数名称: queue_get_head_node
 * 功能描述: 获取队列头部数据节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回头节点指针 失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_get_head_node(queue_head_s_type* queue_head);

/***********************************************************************
 * 函数名称: queue_get_tail_node
 * 功能描述: 获取队列尾部数据节点
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回尾部节点指针 失败返回NULL
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
queue_node_s_type* queue_get_tail_node(queue_head_s_type* queue_head);

/***********************************************************************
 * 函数名称: queue_destory
 * 功能描述: 链表销毁
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_destory(queue_head_s_type* queue_head);

/***********************************************************************
 * 函数名称: queue_init
 * 功能描述: 队列初始化
 * 输    入:queue_head 队列头
 * 输    出: 无
 * 返 回 值: 成功返回0 失败返回对应错误码
 * 其    他:
 * 日    期: 2022/11/23
 * 作    者: axk
 ***********************************************************************/
int queue_init(queue_head_s_type* queue_head);
/****************************QUEUE_API 函数声明 end****************************************************/
#ifdef __cplusplus
}
#endif
#endif

队列接口测试代码

/*********************************************************************
 * 版权所有 (c) 2021-2022  axk. 保留所有版权
 * 文件名称: queue_test.c
 * 文件描述: 队列接口测试文件
 * 作    者: axk
 * 创建日期: 2022/11/23
 * 作    者                 日    期                 版    本          修改摘要
 * axk                   2022/11/23               1.0           文件创建
**********************************************************************/


/* 示例代码数据内容是char*类型字符串 实际使用可以是任意类型指针 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "queue_api.h"
#include "axk_base_data_type.h"

void print_queue(queue_head_s_type* queue_head)
{
    
    
    queue_node_s_type* tmp_node = NULL;
    int i = 0;
    if (NULL == queue_head || 0 == queue_head->node_num)
    {
    
    
        printf("curr queue is NULL!\n");
        return ;
    }

    tmp_node = queue_head->head;
    while (NULL != tmp_node)
    {
    
    
        printf("node %d content %s.\n", i++, (char*)tmp_node->data);
        tmp_node = tmp_node->next;
    }
}

int main(void)
{
    
    
    int menu = 0;
    queue_head_s_type queue_head;
    memset(&queue_head, 0x0, sizeof(queue_head_s_type));

    queue_init(&queue_head);

    while (1)
    {
    
    
        print_queue(&queue_head);
        menu = 0;
        printf("please select menu: \n" \
                "1.queue init \n" \
                "2.queue destory\n" \
                "3.queue push\n" \
                "4.queue pop\n" \
                "5.get queue head data\n" \
                "6.get queue tail data\n" \
                "0.exit \n");

        scanf("%d", &menu);

        switch (menu)
        {
    
    
            case 1:
            {
    
    
                queue_init(&queue_head);
                break;
            }
            case 2:
            {
    
    
                queue_destory(&queue_head);
                break;
            }
            case 3:
            {
    
    
                char* data = (char*)malloc(128);
                if (NULL == data)
                {
    
    
                    printf("\nmalloc failed!\n");
                    break;
                }
                memset(data, 0x0, 128);
                printf("please input data:\n");
                scanf("%s", data);
                queue_push(&queue_head, data, free);
                break;
            }
            case 4:
            {
    
    
                queue_node_s_type* tmp_node = queue_pop(&queue_head);
                if (NULL != tmp_node)
                {
    
    
                    printf("node data is %s\n", (char*)tmp_node->data);
                    free(tmp_node->data);
                    free(tmp_node);
                }
                else
                {
    
    
                    printf("queue is NULL!\n");
                }
                break;
            }
            case 5:
            {
    
    
                queue_node_s_type* tmp_node = queue_get_head_node(&queue_head);
                if (NULL != tmp_node)
                {
    
    
                    printf("node data is %s\n", (char*)tmp_node->data);
                }
                else
                {
    
    
                    printf("queue is NULL!\n");
                }
                break;
            }
            case 6:
            {
    
    
                queue_node_s_type* tmp_node = queue_get_tail_node(&queue_head);
                if (NULL != tmp_node)
                {
    
    
                    printf("node data is %s\n", (char*)tmp_node->data);
                }
                else
                {
    
    
                    printf("queue is NULL!\n");
                }
                break;
            }
            case 0:
            {
    
    
                exit(0);
                break;
            }

            default:
            {
    
    
                printf("nosuppurt menu %d!!!\n", menu);
                break;
            }
        }
    }

    queue_destory(&queue_head);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38721267/article/details/128116593
今日推荐