zoukankan      html  css  js  c++  java
  • 单链表

    /**
     * @file                  single_linked_list.c
     * @author            libra
     * @date                  2016年2月24日
     * @version            初稿
    */
    #include <stdlib.h>
    #include <string.h>
    #include "single_linked_list.h"
    
    /**
     *@brief:         list_init
     *@details:        Initializes the linked list specified by list. This operation must  be called for a linked list before the list can be used with any other operation.
     *              Thedestroyargument provides a way to free dynamically allocated data when  list_destroy is called. For example, if the list contains data dynamically allocated
     *              usingmalloc, destroyshould be set to free to free the data as the linked list is destroyed. For structured data containing several dynamically allocated members,
     *              destroyshould be set to a user-defined function that callsfree for each dynamically allocated member as well as for the structure itself.
     *              For a linked list containing data that should not be freed, destroyshould be set to NULL.
     *@param[in][out]       List *list
     *@param[in]              void (*destroy)(void *data)
     *@retval:               None
     */
    void list_init(List *list, void (*destroy)(void *data))
    {
        /*Initialize the list.*/
        list->size = 0;
    
        list->destroy = destroy;
    
        list->head = NULL;
    
        list->tail = NULL;
    
        return;
    }
    
    /**
     *@brief:         list_destroy
     *@details:        Destroys the linked list specified bylist. No other operations are permitted after calling list_destroy unless list_init is called again.
     *              The list_destroyoperation removes all elements from a linked list and calls the function passed asdestroyto list_init once for each element as it is removed,
     *              provided destroywas not set to NULL.
     *@param[in][out]    List *list
     *@retval:        None
     */
    void list_destroy(List *list)
    {
        void               *data;
        /*Remove each element.*/
        while (list_size(list) > 0)
        {
            if (list_rem_next(list, NULL, (void **)&data) == 0 && list->destroy != NULL)
            {
                /*Call a user-defined function to free dynamically allocated data.*/
                list->destroy(data);
            }
        }
    
        /*No operations are allowed now, but clear the structure as a precaution.*/
        memset(list, 0, sizeof(List));
        return;
    }
    
    /**
     *@brief:          list_ins_next
     *@details:         Inserts an element just after elementin the linked list specified bylist.Ifelementis NULL, the new element is inserted at the head of the list.
     *               The new element contains a pointer todata, so the memory referenced by data should remain valid as long as the element remains in the list.
     *               It is the responsibility of the caller to manage the storage associated with data.
     *@param[in][out] List *list
     *@param[in][out] ListElmt *element
     *@param[in]      const void *data
     *@retval:          0 if inserting the element is successful, or –1 otherwise.
     */
    int list_ins_next(List *list, ListElmt *element, const void *data)
    {
    
        ListElmt           *new_element;
        /*Allocate storage for the element.*/
        if ((new_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL)
        {
            return -1;
        }
    
        /*Insert the element into the list.*/
        new_element->data = (void *)data;
    
        if (element == NULL)
        {
            /*Handle insertion at the head of the list.*/
            if (list_size(list) == 0)
            {
                list->tail = new_element;
            }
    
            new_element->next = list->head;
    
            list->head = new_element;
        }
        else
        {
            /* Handle insertion somewhere other than at the head. */
            if (element->next == NULL)
            {
                list->tail = new_element;
            }
    
            new_element->next = element->next;
    
            element->next = new_element;
        }
        /*Adjust the size of the list to account for the inserted element.*/
        list->size++;
        return 0;
    }
    
    /**
     *@brief:         list_rem_next
     *@details:        Removes the element just afterelementfrom the linked list specified by list.Ifelementis NULL, the element at the head of the list is removed.
     *              Upon return,datapoints to the data stored in the element that was removed. It is
     *              the responsibility of the caller to manage the storage associated with the data.
     *@param[in][out] List *list
     *@param[in][out] ListElmt *element
     *@param[out]     void **data
    
     *@retval:        0 if removing the element is successful, or –1 otherwise.
     */
    int list_rem_next(List *list, ListElmt *element, void **data)
    {
        ListElmt           *old_element;
        /*Do not allow removal from an empty list.*/
        if (list_size(list) == 0)
        {
            return -1;
        }
    
        /* Remove the element from the list.*/
        if (element == NULL)
        {
            /*Handle removal from the head of the list.*/
            *data = list->head->data;
    
            old_element = list->head;
    
            list->head = list->head->next;
    
            if (list_size(list) == 1)
            {
                list->tail = NULL;
            }
        }
        else
        {
            /*Handle removal from somewhere other than the head.*/
            if (element->next == NULL)
            {
                return -1;
            }
    
    
            *data = element->next->data;
    
            old_element = element->next;
    
            element->next = element->next->next;
            if (element->next == NULL)
            {
                list->tail = element;
            }
                
        }
        /*Free the storage allocated by the abstract data type. */
        free(old_element);
        /*Adjust the size of the list to account for the removed element.*/
        list->size--;
        return 0;
    }
    View Code
    /**
     * @file                single_linked_list.h
     * @author            libra
     * @date            2016年2月24日
     * @version            初稿
     * @par                版权所有 (C), 2013-2023, 天道酬勤
     * @par History:
     * 1.日    期:         2016年2月24日
     *   作    者:         libra
     *   修改内容:    创建文件
    */
    #ifndef __SINGLE_LINKED_LIST_H__
    #define __SINGLE_LINKED_LIST_H__
    
    
    #ifdef __cplusplus
    #if __cplusplus
    extern "C"{
    #endif
    #endif /* __cplusplus */
    
    
    /*
     *@brief:    ListElmt
     *@details: Define a structure for linked list elements.
     */
    typedef struct ListElmt_
    {
        void               *data; //!< 
        struct ListElmt_   *next; //!< 
    } ListElmt;
    
    /*
     *@brief:    ListElmt
     *@details: Define a structure for linked lists.
     */
    typedef struct List_
    {
        int                size                                         //!< 
        int                (*match)(const void *key1, const void *key2);//!< 
        void               (*destroy)(void *data);                      //!< 
        ListElmt           *head;                                       //!< 
        ListElmt           *tail;                                       //!< 
    } List;
    
    /*Public Interface*/
    extern void list_destroy(List *list);
    extern void list_init(List *list, void (*destroy)(void *data));
    extern int list_ins_next(List *list, ListElmt *element, const void *data);
    extern int list_rem_next(List *list, ListElmt *element, void **data);
    
    #define list_size(list) ((list)->size)
    
    #define list_head(list) ((list)->head)
    
    #define list_tail(list) ((list)->tail)
    
    #define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)
    
    #define list_is_tail(element) ((element)->next == NULL ? 1 : 0)
    
    #define list_data(element) ((element)->data)
    
    #define list_next(element) ((element)->next)
    
    
    #ifdef __cplusplus
    #if __cplusplus
    }
    #endif
    #endif /* __cplusplus */
    
    
    #endif /* __SINGLE_LINKED_LIST_H__ */
    View Code
    #include <string.h>
    #include "single_linked_list.h"
    
    /**
     *@brief:         print_list
     *@param[in]      const List *list  
     *@retval:        None
     */
    static void print_list(const List *list)
    {
    
        ListElmt *element;
        int *data;
        int i;
    
        /*Display the linked list.*/
    
        printf("List size is %d
    ", list_size(list));
    
        i = 0;
        
        element = list_head(list);
    
        while (1)
        {
    
            data = list_data(element);
            
            printf("list[%03d]=%03d
    ", i, *data);
            
            i++;
            
            if (list_is_tail(element))
            {
                break;
            }        
            else
            {
                element = list_next(element);
            }
        }
    
        return;
    
    }
    
    /**
     *@brief:         main
     *@param[in]    void  
     *@param[out]    无
     *@retval:        
     */
    int main(void)
    {
    
    
        List   list;
        ListElmt   *element;
        int *data;
        int i;
        
        /* Initialize the linked list. */
        list_init(&list, free);
        
        /* Perform some linked list operations.*/
        element = list_head(&list);
        for (i = 10; i > 0; i--)
        {
            if ((data = (int *)malloc(sizeof(int))) == NULL)
            {
                return;
            }        
            *data = i;
            if (list_ins_next(&list, NULL, data) != 0)
            {
                return;
            }    
        }
        print_list(&list);
    
        element = list_head(&list);
        for (i = 0; i < 7; i++)
        {
            element = list_next(element);
        }
        data = list_data(element);    
        
        printf("Removing an element after the one containing %03d
    ", *data);
        
        if (list_rem_next(&list, element, (void **)&data) != 0)
        {
            return;
        }    
        print_list(&list);
        
        printf("Inserting 011 at the tail of the list
    ");
        *data = 11;    
        if (list_ins_next(&list, list_tail(&list), data) != 0)
        {
            return;
        }
        print_list(&list);
    
        printf("Removing an element after the first element
    ");
        element = list_head(&list);
        if (list_rem_next(&list, element, (void **)&data) != 0)
        {
            return;
        }
        print_list(&list);
    
        printf("Inserting 012 at the head of the list
    ");
        *data = 12;
        if (list_ins_next(&list, NULL, data) != 0)
        {
            return;    
        }
        print_list(&list);
    
        printf("Iterating and removing the fourth element
    ");
        element = list_head(&list);
        element = list_next(element);
        element = list_next(element);
        if (list_rem_next(&list, element, (void **)&data) != 0)
        {
            return;
        }
        print_list(&list);
    
        printf("Inserting 013 after the first element
    ");
        *data = 13;
        if (list_ins_next(&list, list_head(&list), data) != 0)
        {
            return;
        }
        print_list(&list);
    
        i = list_is_head(&list, list_head(&list));
        printf( "Testing list_is_head...Value=%d (1=OK)
    ", i);
        i = list_is_head(&list, list_tail(&list));
        printf( "Testing list_is_head...Value=%d (0=OK)
    ", i);
        i = list_is_tail(list_tail(&list));
        printf( "Testing list_is_tail...Value=%d (1=OK)
    ", i);
        i = list_is_tail(list_head(&list));
        printf( "Testing list_is_tail...Value=%d (0=OK)
    ", i);
    
        /*Destroy the linked list.*/
    
        printf("Destroying the list
    ");
        list_destroy(&list);
    }
  • 相关阅读:
    注解
    使用反射机制调用属性和私有成员与代理模式的介绍
    动态代理模式
    SVN的安装与常用功能使用以及解决安装配置过程中的一些错误
    企业私服
    -Java-log4j
    List,Set,Map用法以及区别
    接口和抽象类有什么区别
    Dalvik opcodes
    外派公司或者外包公司,真的适合选择吗?
  • 原文地址:https://www.cnblogs.com/libra13179/p/7210130.html
Copyright © 2011-2022 走看看