3、单链表

来源:互联网 发布:logo设计软件下载 编辑:程序博客网 时间:2024/06/14 08:17

1、链表需要动态开辟存储空间,链表元素连接在一起,但在内存空间中它们是分散开的。

2、单链表只能以一个方向进行遍历

3、释放的是data指向的内存,而不是分配给指针变量data本身的内存空间

int *data;data = (int*)malloc(sizeof(int));free(data);

4、single_list.h

#ifndef LIST_H#define LIST_H//链表单个节点信息 typedef struct _ListElmt{    void *data;//data指向另一个空间数据,删除链表需要:                //1)释放另外空间数据free(data);2)释放单个链表节点    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; #define list_size(list)     (list->size)#define list_head(list)     (list->head)#define list_tail(list)     (list->tail)#define list_next(element)      (element->next)#define list_data(element)      (element->data)#define is_head(list,element)       ((element == list->head) ? 1 :0)#define is_tail(element)            ((element->next == NULL) ? 1 :0)void list_init(List *list, int size, void (*destroy)(void *data));int list_ins_next(List *list, ListElmt *element, void *data);   int list_rem_next(List *list, ListElmt *element);#endif

5、single_list.c

#include <stdio.h>#include <stdlib.h> #include "single_list.h"//初始化,此时链表为空 void list_init(List *list, int size, void (*destroy)(void *data)){    list->size = size;    list->destroy = destroy;    list->head = NULL;    list->tail = NULL;    return;} //在element后面插入新节点 ,如果 element为空表示向头结点前面插入 int list_ins_next(List *list, ListElmt *element, void *data){    ListElmt *new_element;    if(( new_element = (ListElmt *)malloc(sizeof(ListElmt)) ) == NULL)    {        return -1;    }    new_element->data = (void *)data;    //如果 element为空表示向头结点前面插入    if(element == NULL)    {        //如果链表中还没有节点,则首尾节点都是新节点         if(list->size==0)            list->tail=new_element;         new_element->next = list->head;        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;}//删除element后面的节点,如果element为空则删除头结点 //data保存删除的节点中数据的地址,该地址是指向具体数据块的data变量的地址 int list_rem_next(List *list, ListElmt *element, void **data){    ListElmt *old_element;    if(list->size == 0)    {        return -1;    }    if(element == NULL)    {        *data = list->head->data;           old_element = list->head;        list->head = list->head->next;        if(list->size==1)            list->tail=NULL;    }    else    {        //如果element后面无节点可删除,报错         if(element->next == NULL)            return -1;        *data = element->next->data;        old_element = element->next;         element->next = element->next->next ;        //删除 element后面的节点,element可能为最末端的节点         if(element->next == NULL)            list->tail = element;    }    list->size--;    free(old_element);    return 0;}void list_destroy(List *list){    void *data;    while(list->size>0)    {        if(list_rem_next(list, NULL, (void **)&data)==0 && list->destroy != NULL)        {            //不仅要删除链表节点还要 删除该节点data指向的数据块             list->destroy(data);        }    }}
原创粉丝点击