单向链表顾名思义它是一种链表,而且是单向的,每个元素会保存下一个元素引用,和数组类似,插入的时候比数组快,没有数据的移动
先看头文件:
#ifndef LINK_LIST_H
#define LINK_LIST_H
#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_size(list) ((list)->size)
#define list_data(element) ((element)->data)
#define list_next(elemetn) ((element)->next)
typedef struct ListElmt_{
void * data;
struct ListElmt_ * next;
} ListElmt,*ListElmtP;
typedef struct LinkList_{
int size;
ListElmtP head;
ListElmtP tail;
void (*destroy)(void *data);
int (*macth)(const void*key1,const void * key2);
} LinkList ,* LinkListP;
void list_init(LinkListP list,void (*destroy) (void *data));
void list_destroy(LinkListP list);
int list_ins_next(LinkListP list,ListElmtP element, void *data);
int list_rm_next(LinkListP list,ListElmtP element,void **data);
LinkListP reverse_copy(const LinkListP list);
void reverse(LinkListP list);
#endif
头文件定义了两个结构体,一个是节点一个链表,链表保存了长度和头部节点和为节点以及回收方法,还定义了一些方法以及宏
源文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linkList.h"
void list_init(LinkListP list,void (*destroy) (void *data)){
list->head=NULL;
list->tail=NULL;
list->size=0;
list->destroy=destroy;
}
void list_destroy(LinkListP list){
void *data;
while (list_size(list)>0) {
if(list_rm_next(list,NULL,(void**)&data)&&list->destroy!=NULL)
list->destroy(data);
}
memset(list,0,sizeof(LinkList));
}
int list_ins_next(LinkListP list,ListElmtP element, void *data){
ListElmtP ele=(ListElmtP)malloc(sizeof(ListElmt));
if(!ele)
return 0;
ele->data=data;
if(element==NULL){
ele->next=NULL;
if(list_size(list)==0){
list->head=ele;
}else{
list->tail->next=ele;
}
list->tail=ele;
}else{
ele->next=element->next;
element->next=ele;
if(list_is_tail(element))
list->tail=ele;
}
list->size++;
return 1;
}
int list_rm_next(LinkListP list,ListElmtP element,void **data){
if(list_size(list)==0)
return 0;
if(element==NULL){
ListElmtP rm=list->head;
list->head=rm->next;
*data=rm->data;
free(rm);
if(list_size(list)==0){
list->tail=NULL;
list->head=NULL;
}
}else{
ListElmtP rm=element->next;
if(rm==NULL)
return 0;
element->next=rm->next;
*data=rm->data;
free(rm);
}
list->size--;
return 1;
}
LinkListP reverse_copy(const LinkListP list){
LinkListP reverseP=malloc(sizeof(LinkList));
if(!reverseP)
return NULL;
int size=list_size(list);
if(size==0)
return reverseP;
if(size>0){
ListElmtP head=malloc(sizeof(ListElmt));
if(!head)
return reverseP;
head->data=list->tail->data;
head->next=NULL;
reverseP->head=head;
reverseP->tail=head;
if(size>1){
ListElmtP next=list->head;
while (next&&!list_is_tail(next)) {
list_ins_next(reverseP,head,next->data);
next=next->next;
}
}
}
return reverseP;
}
void reverse(LinkListP list){
int size=list_size(list);
if(size==0)
return;
ListElmtP head=list->head;
ListElmtP tail=list->tail;
list->head=tail;
list->tail=head;
ListElmtP pre=head;
ListElmtP next=pre->next;
while (next) {
ListElmtP ele=next->next;
next->next=pre;
pre=next;
next=ele;
}
head->next=NULL;
}
int main(void){
LinkList list;
list_init(&list,free);
int i=0;
for (; i<5; i++) {
int *p=malloc(sizeof(int));
*p=i;
printf("%d\n",list_ins_next(&list,NULL,p));
}
LinkListP re=reverse_copy(&list);
ListElmtP next=re->head;
while (next) {
printf("%d\t",*((int *)(next->data)));
next=next->next;
}
printf("\n");
next=list.head;
while (next) {
printf("%d\t",*((int *)(next->data)));
next=next->next;
}
int *p;
printf("\n");
list_rm_next(&list,NULL,(void **)(&p));
printf("%d\n",*p);
reverse(&list);
next=list.head;
while (next) {
printf("%d\t",*((int *)(next->data)));
next=next->next;
}
printf("\n");
}