【数据结构回顾】单链表实现

/************************************************************************* > File Name: list.h > Author:Gin.TaMa > Mail:1137554811@qq.com > Created Time: 2019年03月26日 星期二 15时10分27秒 ************************************************************************/

#ifndef _LIST_H
#define _LIST_H

typedef struct ListElmt_{
   
    void *data;
    struct ListElmt_ *next;
}ListElmt;

typedef struct List_{
   
    int size;
    int (*match)(const void *key1,const void *key2);
    void (*destroy)(void*data);
    ListElmt *head;
    ListElmt *tail;
}List;

void list_init(List *list,void (*destroy)(void * data));
void list_destory(List *list);
int list_rem_next(List *list,ListElmt *element,void **data);
int list_ins_next(List *list,ListElmt *element,const void *data);

#define list_size(list) ((list) -> size)
#define list_head(list) ((list) -> head)
#define list_tail(list) ((list) -> tail)
#define list_data(element) ((element) -> data)
#define list_next(element) ((element) -> next)

#endif

这个东西大家肯定是非常熟悉的啦。

然后今天学习一下这个单链表的设计

关于list.h

  1. 分为listElmt 和 List 两个结构体

  2. listElmt 的数据部分是 设计的void* 这个格式(泛型)

  3. list 维护了destroy 和 match ,这意味着,data 的free 交由destroy 处理

  4. 对于list_rem_next(list *listlist *element, void** data);

    将data的释放 交由调用他的函数处理。

这也就是说,我这个数据结构只负责维护一个链表,至于你放链表里什么东西,怎么处理,怎么释放,我都交由上层函数处理。

关于list.c

/************************************************************************* > File Name: list.c > Author:Gin.TaMa > Mail:1137554811@qq.com > Created Time: 2019年03月26日 星期二 15时18分43秒 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "list.h"

void list_init(List *list,void (*destroy)(void *data)){
   
    list -> size = 0;
    list -> destroy = destroy;
    list -> head = NULL;
    list -> tail = NULL;
    return;
}

void list_destory(List *list){
   
    void *data;
    while(list_size(list) > 0){
   
        if(list_rem_next(list,NULL,(void **)&data) == 0 &&list->destroy){
   
           list -> destroy(data); 
        }
    }
}

int list_ins_next(List *list,ListElmt *element,const void *data){
   
    ListElmt * new_element;
    new_element = malloc(sizeof(ListElmt));
    new_element -> data = (void *)data;
    if(element == NULL){
   
        if(list -> size == 0)
            list -> tail = new_element;
        new_element -> next = list -> head -> next;
        list -> head = new_element;
    }else{
   
        if(element -> next == NULL)
            list -> tail = new_element;
        new_element -> next = element -> next;
        element -> next = new_element;
    }
    list -> size ++;
    return 0;
}

int list_rem_next(List *list,ListElmt *element,void **data){
   
    ListElmt *old_element;
    if(list_size(list) == 0)return -1;
    if(element == NULL){
   
        old_element = list -> head;
        list -> head = list -> head -> next;
        if(list -> size == 1)list -> tail = NULL;
    }else{
   
        if(element -> next == NULL)return -1;
        old_element = element -> next;
        element -> next = element -> next -> next;
        if(element -> next == NULL)list -> tail = element;
    }
    *data = old_element -> data; 
    list -> size --;
    free(old_element);
    return 0;
}

这里具体的实现需要注意的是对于头尾,以及size的维护。

还有别名的使用。