一種基於雙向鏈表設計的list數據存儲操作接口(加入類迭代器設計)

源碼的下載地址:https://download.csdn.net/download/xiyuan255/12372494
/*
 * File name    : xy_list_code.c
 *
 * Created on    : 2019年8月29日10:39:35
 * Author          : Firmware of xiyuan255
 * Version        : 2.0
 * Language        : C
 * Copyright    : Copyright (C) 2019, xiyuan255 Inc.
 *
 */
#include <stdio.h>
#include <malloc.h>
#include "xy_clist_source.h"

typedef struct s_link_list
{    
    PDATA_T ptr_data;
    struct s_link_list *ptr_prev;
    struct s_link_list *ptr_next;
    
} link_list_t, *link_list_p;

typedef struct _s_clist_
{
    link_list_p    ptr_head;    /**< link_list_p鏈表的頭指針 */
    link_list_p    ptr_tail;    /**< link_list_p鏈表的尾指針 */
    
} clist_t, *clist_p;

#define CLIST_HEAD(clist)    ( ((clist_p)clist)->ptr_head )
#define CLIST_TAIL(clist)    ( ((clist_p)clist)->ptr_tail )

/** 
 * \brief 通過迭代器指針解析數據指針
 * \param ptr_iterator    [in] 參數名稱,迭代器指針
 * \return
 *            !NULL     : 數據指針            \n
 *            NULL    : 不存在    \n
 */
__STATIC PDATA_T c_list_data(PITERATOR_T ptr_iterator)
{
    return ( (NULL != ptr_iterator)? (((link_list_p)ptr_iterator->_value)->ptr_data) : NULL );
}

/** 
 * \brief 獲取迭代器的前一個指針
 * \param ptr_iterator    [in] 參數名稱,迭代器指針
 * \return
 *            !NULL     : 迭代器指針            \n
 *            NULL    : 不存在    \n
 */
__STATIC void c_list_prev(PITERATOR_T ptr_iterator)
{        
    if (NULL != ptr_iterator)
    {
        ptr_iterator->_value = ((link_list_p)ptr_iterator->_value)->ptr_prev;
    }
}

/** 
 * \brief 獲取迭代器的後一個指針
 * \param ptr_iterator    [in] 參數名稱,迭代器指針
 * \return
 *            !NULL     : 迭代器指針            \n
 *            NULL    : 不存在    \n
 */
__STATIC void c_list_next(PITERATOR_T ptr_iterator)
{    
    if (NULL != ptr_iterator)
    {
        ptr_iterator->_value = ((link_list_p)ptr_iterator->_value)->ptr_next;
    }
}

/** 
 * \brief 判斷兩個迭代器指針是否相等
 * \param ptr_iter1    [in] 參數名稱,迭代器指針1 
 * \param ptr_iter2    [in] 參數名稱,迭代器指針2
 * \return
 *            true     : 相等    \n
 *            false    : 不相等    \n
 */
__STATIC boolean c_list_equal(PITERATOR_T ptr_iter1, PITERATOR_T ptr_iter2)
{    
    return (  (ptr_iter1 && ptr_iter2) && (ptr_iter1->_value == ptr_iter2->_value) );
}

__STATIC iterator_ft sg_list_iterator = {
    c_list_data,        
    c_list_prev,
    c_list_next,
    c_list_equal,
};

/** 
 * \brief 初始化CLIST對象
 * \return
 *        !NULL    : 成功返回句柄        \n
 *           NULL    : 初始化失敗            \n
 */
PUBLIC CLIST c_list_init(void)
{
    clist_p clist = NULL;

    clist = (clist_p)calloc(sizeof(char), sizeof(clist_t)); 
    if (NULL == clist) {
        return NULL;
    }
    clist->ptr_head    = (link_list_p)clist;
    clist->ptr_tail    = (link_list_p)clist;

    return (CLIST)clist;
}

/** 
 * \brief 清空CLIST對象
 * \return
 */
PUBLIC void c_list_clear(CLIST clist)
{    
    link_list_p ptr_node1 = NULL;
    link_list_p ptr_node2 = NULL;

    if (NULL == clist) {
        return ;
    }

    ptr_node2 = CLIST_HEAD(clist);
    while (ptr_node2 != clist)
    {
        ptr_node1 = ptr_node2->ptr_next;
        free(ptr_node2);
        ptr_node2 = ptr_node1;
    }

    CLIST_HEAD(clist) = clist;
    CLIST_TAIL(clist) = clist;

    return ;
}

/** 
 * \brief 銷燬CLIST對象 
 * \param ptr_clist    [in] 參數名稱,CLIST對象指針
 * \return
 */
PUBLIC void c_list_destroy(CLIST *ptr_clist)
{
    if (NULL != ptr_clist)
    {        
        c_list_clear(*ptr_clist);
        
        free(*ptr_clist);
        *ptr_clist = NULL;
    }
}

/** 
 * \brief 計算CLIST對象的長度 
 * \param clist    [in] 參數名稱,CLIST對象
 * \return
 *         返回對象長度
 */
PUBLIC int c_list_size(CLIST clist)
{    
    int count = 0;
    link_list_p ptr_node = NULL;

    if (NULL == clist) {
        return 0;
    }

    ptr_node = CLIST_HEAD(clist);
    while (ptr_node != clist)
    {
        count++;
        ptr_node = ptr_node->ptr_next;
    }
    
    return count;
}

/** 
 * \brief 判斷CLIST對象的是否爲空 
 * \param clist    [in] 參數名稱,CLIST對象
 * \return
 *           true    : 爲空    \n
 *           false   : 不爲空 \n
 */
PUBLIC boolean c_list_empty(CLIST clist)
{    
    return ( (NULL == clist || (clist == CLIST_HEAD(clist))) ? true : false );
}

/** 
 * \brief 獲取CLIST對象的頭迭代器 
 * \param clist    [in] 參數名稱,CLIST對象
 * \return
 *         返回對象的頭迭代器
 */
PUBLIC ITERATOR_T c_list_begin(CLIST clist)
{
    ITERATOR_T iterator = {NULL, clist};
    
    if (NULL != clist)
    {
        iterator._pft = &sg_list_iterator;
        iterator._value = CLIST_HEAD(clist);
    }

    return iterator;
}

/** 
 * \brief 獲取CLIST對象的尾迭代器 
 * \param clist    [in] 參數名稱,CLIST對象
 * \return
 *         返回對象的尾迭代器
 */
PUBLIC ITERATOR_T c_list_tail(CLIST clist)
{
    ITERATOR_T iterator = {NULL, clist};
    
    if (NULL != clist)
    {
        iterator._pft = &sg_list_iterator;
        iterator._value = CLIST_TAIL(clist);
    }

    return iterator;
}

/** 
 * \brief 獲取CLIST對象的結束迭代器 
 * \param clist    [in] 參數名稱,CLIST對象
 * \return
 *         返回對象的結束迭代器
 */
PUBLIC ITERATOR_T c_list_end(CLIST clist)
{    
    ITERATOR_T iterator = {NULL, clist};

    return iterator;
}

/** 
 * \brief 向CLIST對象插入數據
 * \param clist        [in] 參數名稱,CLIST對象 
 * \param pos        [in] 參數名稱,迭代器指針 
 * \param ptr_data    [in] 參數名稱,數據指針
 * \return
 *         -1    : 動態內存分配失敗
 *          0    : 插入成功
 */
PUBLIC int c_list_insert(CLIST clist, PITERATOR_T pos, const PDATA_T ptr_data)
{
    link_list_p ptr_node = CLIST_HEAD(clist); // 取頭結點指針
    link_list_p ptr_new  = (link_list_p)calloc(sizeof(char), sizeof(link_list_t));
    if (NULL == ptr_new) {
        c_error("[%s, %s, %d] memory allocation failed.\n", __FILE__, __FUNCTION__, __LINE__);
        return -1;
    }
    
    ptr_new->ptr_data = (PDATA_T)ptr_data;

    if (clist == CLIST_HEAD(clist))
    {
        ptr_new->ptr_next = (link_list_p)clist;
        ptr_new->ptr_prev = (link_list_p)clist;
        CLIST_HEAD(clist) = ptr_new;
        CLIST_TAIL(clist) = ptr_new;
    }
    else
    {
        if (pos->_value == CLIST_HEAD(clist)) // 插入到第一個節點
        {            
            ptr_new->ptr_next  = CLIST_HEAD(clist);
            ptr_new->ptr_prev  = (link_list_p)clist;
            CLIST_HEAD(clist)->ptr_prev = ptr_new;
            CLIST_HEAD(clist) = ptr_new;            
        }
        else if (pos->_value == CLIST_TAIL(clist)) // 插入到最後一個節點
        {            
            ptr_new->ptr_next  = (link_list_p)clist;
            ptr_new->ptr_prev  = CLIST_TAIL(clist);
            CLIST_TAIL(clist)->ptr_next = ptr_new;
            CLIST_TAIL(clist) = ptr_new;            
        }
        else // 插入到中間節點
        {
            while (ptr_node != clist)  
            {
                if (pos->_value == ptr_node) {
                    break;
                }
                ptr_node = ptr_node->ptr_next;
            }
            ptr_new->ptr_prev = ptr_node->ptr_prev;
            ptr_new->ptr_next = ptr_node;
            ptr_node->ptr_prev->ptr_next = ptr_new;
            ptr_node->ptr_prev = ptr_new;
        }

    }
        
    return 0;
}

/** 
 * \brief 擦除CLIST對象的數據
 * \param clist        [in] 參數名稱,CLIST對象 
 * \param position    [in] 參數名稱,迭代器指針 
 * \return
 */
PUBLIC void c_list_erase(CLIST clist, PITERATOR_T position)
{
    link_list_p ptr_node = NULL;
    
    if (NULL != clist && clist != position)
    {
        ptr_node = (link_list_p)(position->_value);        
        if (ptr_node == CLIST_HEAD(clist))
        {
            if (CLIST_HEAD(clist) == CLIST_TAIL(clist))
            {
                CLIST_HEAD(clist) = (link_list_p)clist;
                CLIST_TAIL(clist) = (link_list_p)clist;
            }
            else
            {
                ptr_node->ptr_next->ptr_prev = (link_list_p)clist;
                CLIST_HEAD(clist) = ptr_node->ptr_next;
            }            
        }
        else if (ptr_node == CLIST_TAIL(clist))
        {
            ptr_node->ptr_prev->ptr_next = (link_list_p)clist;
            CLIST_TAIL(clist) = ptr_node->ptr_prev;
        }
        else
        {
            ptr_node->ptr_prev->ptr_next = ptr_node->ptr_next;
        }
        
        free(ptr_node);
    }
}

/** 
 * \brief 對CLIST對象的數據進行排序
 * \param clist        [in] 參數名稱,CLIST對象 
 * \param compare    [in] 參數名稱,比較函數 
 * \return
 *         0    : 成功
 */
PUBLIC int c_list_sort(CLIST clist, c_compare_t compare)
{
    PDATA_T ptr_temp_node = NULL;
    link_list_p ptr_node1 = NULL;
    link_list_p ptr_node2 = NULL;
    
    CHECK_PARAM_IS_NULL_RET(clist, -1);        
    CHECK_PARAM_IS_NULL_RET(compare, -1);

    for (ptr_node1 = CLIST_HEAD(clist); ptr_node1->ptr_next != clist; ptr_node1 = ptr_node1->ptr_next)
    {
        for (ptr_node2 = CLIST_HEAD(clist); ptr_node2->ptr_next != clist; ptr_node2 = ptr_node2->ptr_next)
        {
            if (compare(ptr_node2->ptr_data, ptr_node2->ptr_next->ptr_data) > 0)
            {
                ptr_temp_node                    = ptr_node2->ptr_data;
                ptr_node2->ptr_data              = ptr_node2->ptr_next->ptr_data;
                ptr_node2->ptr_next->ptr_data = ptr_temp_node;
            }
        }
    }    
    return 0;
}

/** 
 * \brief 遍歷CLIST對象的數據
 * \param clist        [in] 參數名稱,CLIST對象 
 * \param print_data   [in] 參數名稱,數據對應的打印函數 
 * \return
 */
PUBLIC void c_list_traverse(CLIST clist, c_print_data_t print_data)
{
    link_list_p ptr_node = NULL;

    if (NULL != clist)
    {
        for (ptr_node = CLIST_HEAD(clist); ptr_node != clist; ptr_node = ptr_node->ptr_next)
        {
            if (print_data)
            {
                print_data(ptr_node->ptr_data);
            }
        }    
    }
}

/** 
 * \brief 獲取CLIST對象的隊頭數據
 * \param clist        [in] 參數名稱,CLIST對象 
 * \return 
 *            !NULL     : 數據指針            \n
 *            NULL    : 不存在    \n
 */
PUBLIC PDATA_T c_list_front(CLIST clist)
{    
    if (NULL != clist && clist != CLIST_HEAD(clist))
    {
        return CLIST_HEAD(clist)->ptr_data;
    }
    else
    {
        return NULL;
    }    
}

/** 
 * \brief 獲取CLIST對象的隊尾數據
 * \param clist        [in] 參數名稱,CLIST對象 
 * \return 
 *            !NULL     : 數據指針            \n
 *            NULL    : 不存在    \n
 */
PUBLIC PDATA_T c_list_back(CLIST clist)
{
    if (NULL != clist && clist != CLIST_TAIL(clist))
    {
        return CLIST_TAIL(clist)->ptr_data;
    }
    else
    {
        return NULL;
    }        
}

/** 
 * \brief 向CLIST對象的隊頭插入數據
 * \param clist        [in] 參數名稱,CLIST對象  
 * \param ptr_data    [in] 參數名稱,數據指針
 * \return 
 */
PUBLIC void c_list_push_front(CLIST clist, const PDATA_T ptr_data)
{
    ITERATOR_T position = {NULL, CLIST_HEAD(clist)};
    
    c_list_insert(clist, &position, ptr_data);
}

/** 
 * \brief 向CLIST對象的隊尾插入數據
 * \param clist        [in] 參數名稱,CLIST對象  
 * \param ptr_data    [in] 參數名稱,數據指針
 * \return 
 */
PUBLIC void c_list_push_back(CLIST clist, const PDATA_T ptr_data)
{
    ITERATOR_T position = {NULL, CLIST_TAIL(clist)};
    
    c_list_insert(clist, &position, ptr_data);
}

/** 
 * \brief CLIST對象的隊頭出隊數據
 * \param clist        [in] 參數名稱,CLIST對象  
 * \return 
 */
PUBLIC void c_list_pop_front(CLIST clist)
{
    if (NULL != clist && clist != CLIST_HEAD(clist))
    {
        link_list_p ptr_node = CLIST_HEAD(clist);    
        if (ptr_node == CLIST_TAIL(clist))
        {
            CLIST_HEAD(clist) = (link_list_p)clist;    
            CLIST_TAIL(clist) = (link_list_p)clist;                
        }
        else
        {            
            CLIST_HEAD(clist) = ptr_node->ptr_next;
            ptr_node->ptr_next->ptr_prev = (link_list_p)clist;
        }
        
        free(ptr_node);
    }
}

/** 
 * \brief CLIST對象的隊尾出隊數據
 * \param clist        [in] 參數名稱,CLIST對象  
 * \return 
 */
PUBLIC void c_list_pop_back(CLIST clist)
{
    if (NULL != clist && clist != CLIST_HEAD(clist))
    {
        link_list_p ptr_node = CLIST_TAIL(clist); 
        if (ptr_node == CLIST_HEAD(clist))
        {
            CLIST_HEAD(clist) = (link_list_p)clist;    
            CLIST_TAIL(clist) = (link_list_p)clist;
        }
        else
        {
            CLIST_TAIL(clist) = ptr_node->ptr_prev;
            ptr_node->ptr_prev->ptr_next = (link_list_p)clist;
        }
        
        free(ptr_node);
    }
}

 

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