zoukankan      html  css  js  c++  java
  • 算法精解(C语言描述) 第5章 读书笔记

    第5章

    5.1 单链表

    /*  -------------------------------- list.h --------------------------------  */
    #ifndef LIST_H
    #define LIST_H
    
    #include <stdlib.h>
    
    /*  Define a structure for linked list elements.*/
    typedef struct ListElmt_ 
    {
        void *data;
        struct ListElmt_ *next;
    } ListElmt;
    
    /*  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 ---------------------------  */
    void list_init(List *list, void (*destroy)(void *data));//whl-?其destroy参数的用法?
    void list_destroy(List *list);
    int list_ins_next(List *list, ListElmt *element, const void *data);
    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)
    
    #endif
    /*  -------------------------------- list.c --------------------------------  */
    #include <stdlib.h>
    #include <string.h>
    #include "list.h"
    /*  ------------------------------- list_init ------------------------------  */
    void list_init(List *list, void (*destroy)(void *data))//若链表包含不该释放的数据,则destroy应设置为NULL
    {
        /*  Initialize the list. */
        list->size = 0;
        list->destroy = destroy;//把函数指针成员destroy设置为定义的析构函数
        list->head = NULL;
        list->tail = NULL;
        return;
    }
    /*  ----------------------------- list_destroy -----------------------------  */
    void list_destroy(List *list)//若传给list_init的参数destroy不为NULL,则移除链表中每个元素时都调用该函数一次
    {
        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;
    }
    /*  ----------------------------- list_ins_next ----------------------------  */
    int list_ins_next(List *list, ListElmt *element, const void *data) //在list指定的链表中element后面插入一个新元素
    {
        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;
        new_element->data = (void *)data;
        if (element == NULL) //若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;
    }
    /*  ----------------------------- list_rem_next ----------------------------  */
    int list_rem_next(List *list, ListElmt *element, void **data)//移除由list指定的链表中element后的那个元素
    {
        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)//若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;
    }
  • 相关阅读:
    Linux三种网络连接模式
    hadoop知识点总结
    Wordpress 删除 Storefront 主题的购物车
    英文俚语600句及释义
    雅思口语俚语150句 A-Z of English Idioms: 150 Most Common Expressions
    雅思作文策略总结
    雅思作文高分词汇及词组
    剑桥雅思写作高分范文ESSAY113
    剑桥雅思写作高分范文ESSAY112
    剑桥雅思写作高分范文ESSAY111
  • 原文地址:https://www.cnblogs.com/whl2012/p/3622080.html
Copyright © 2011-2022 走看看