纯C语言(C89)实现简单链表

起因

工作很少接触纯C项目,业余写着玩玩,不断雕琢

目标

纯C实现简单链表,提供方便易用泛型接口,避免依赖

实现

完全封装,隐藏结构体细节,不支持栈创建
拷贝存储,轻微性能代价换来易用性

list.h

#ifndef LIST_H
#define LIST_H
#include <stddef.h>

typedef struct ListItem_ ListItem;
typedef struct List_ List;

extern     List* list_new();
extern      void list_free(List* l);
extern    size_t list_length(List* l);
extern ListItem* list_head(List* l);
extern ListItem* list_tail(List* l);
extern ListItem* list_next(ListItem* e);
extern    size_t list_data(ListItem* e, void** data);
extern       int list_insert_next(List* l, ListItem* e, void* data_in, size_t size);
extern       int list_remove_next(List* l, ListItem* e);

#endif // LIST_H

list.c

#include "list.h"
#include <stdlib.h>
#include <string.h>

typedef unsigned char byte;

typedef struct ListItem_ {
	struct ListItem_* next;
	byte* data;
	size_t size;
} ListItem;

typedef struct List_ {
	size_t count;
	ListItem* head;
	ListItem* tail;
} List;

List* list_new() {
	List* l = calloc(1, sizeof(List));
	return l;
}

void list_free(List* l) {
	while (list_length(l) > 0) {
		list_remove_next(l, 0);
	}
}

size_t list_length(List* l) {
	return l->count;
}

ListItem* list_head(List* l) {
	return l->head;
}

ListItem* list_tail(List* l) {
	return l->tail;
}

ListItem* list_next(ListItem* e) {
	return e->next;
}

size_t list_data(ListItem* e, void** data) {
	if (!e) return 0;
	*data = e->data;
	return e->size;
}

int list_insert_next(List* l, ListItem* e, void* data_in, size_t size) {
	ListItem* e_new = calloc(1, sizeof(ListItem));
	if (!e_new) return -1;
	e_new->data = calloc(size, sizeof(byte));
	if (e_new->data) {
		memcpy(e_new->data, data_in, size);
		e_new->size = size;
	} else {
		free(e_new);
		return -1;
	}
	if (l->count == 0) {
		if (e) return -1;
		l->head = e_new;
		l->tail = e_new;
	} else if (e) {
		e_new->next = e->next;
		e->next = e_new;
		if (!e_new->next) 
			l->tail = e_new;
	} else {
		e_new->next = l->head;
		l->head = e_new;	
	}
	l->count ++;
	return 0;
}

int list_remove_next(List* l, ListItem* e) {
	ListItem* e_next;
	if (l->count == 0) return -1;
	if (e) {
		if (!e->next) return -1;
		e_next = e->next;
		e->next = e_next->next;
	} else {
		e_next = l->head;
		l->head = e_next->next;
		if (l->count == 1) l->tail = 0;
	}
	free(e_next->data);
	free(e_next);
	l->count --;
	return 0;
}

测试

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

int main(int argc, char *argv[]) {
	List* l = list_new();
	ListItem* it;
	size_t l_len = 0;
	int i, x, y, *p, n;
	for (i=0; i<10; i++) {
		list_insert_next(l,0,&i,sizeof(i));
	}
	l_len = list_length(l);
	printf("l_len:%d \n", l_len);
	while (list_length(l) > 0) {
		if (!list_remove_next(l,0)) {
			n = list_data(list_head(l), &p);
			if (n) printf("list_head:%d size:%d \t", *p, n);
			n = list_data(list_tail(l), &p);
			if (n) printf("list_tail:%d size:%d \n", *p, n);		
		}
	}
	list_free(l);
	return 0;
}
l_len:10
list_head:8 size:4      list_tail:0 size:4
list_head:7 size:4      list_tail:0 size:4
list_head:6 size:4      list_tail:0 size:4
list_head:5 size:4      list_tail:0 size:4
list_head:4 size:4      list_tail:0 size:4
list_head:3 size:4      list_tail:0 size:4
list_head:2 size:4      list_tail:0 size:4
list_head:1 size:4      list_tail:0 size:4
list_head:0 size:4      list_tail:0 size:4
posted @ 2019-09-19 00:24  wuyaSama  阅读(468)  评论(0编辑  收藏  举报