链表练习,c实现,简单封装。
"myList.h"
#ifndef _MY_LIST_H_
#define _MY_LIST_H_
typedef struct ListNodeTag{
void *data;
struct ListNodeTag *prev;
struct ListNodeTag *next;
}ListNode, *pListNode;
//NodeCmpfun(s1, s2), s1==s2, return 0; s1>s2, ruturn 1; s1<s2, return -1;
typedef int (*NodeCmpFun)(void *, void *);
typedef void (*ShowDataFun)(void *);
typedef struct ListTag{
int (*push_front)(struct ListTag*, void *data, size_t);
int (*push_back)(struct ListTag*, void *data, size_t);
int (*push)(struct ListTag*, int pos, void *data, size_t);
int (*pop_front)(struct ListTag*);
int (*pop_back)(struct ListTag*);
int (*pop)(struct ListTag*, int pos);
pListNode (*find)(struct ListTag*, void *data, size_t);
pListNode (*begin)(struct ListTag*);
pListNode (*end)(struct ListTag*);
int (*size)(struct ListTag*);
void (*show_list)(struct ListTag*);
//private data, do not modify them directly !!
pListNode head;
pListNode tail;
NodeCmpFun cmpFun;
ShowDataFun show;
int num; //number of list member
int sz; //size of data in the node
}List, *pList;
pList ListCreate(int datasize, NodeCmpFun cmpFun, ShowDataFun show);
int ListDelete(pList);
#endif /*_MY_LIST_H_*/
"myList.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myList.h"
//#define NDEBUG //This one should be in front of #include <assert.h> if define NDEBUG
#include <assert.h>
static pListNode List_NewNode(void *data, size_t sz)
{
pListNode n = (pListNode)malloc(sizeof(ListNode));
if(n == NULL){
perror("malloc");
return NULL;
}
n->data = malloc(sz);
if(n->data == NULL){
perror("malloc");
free(n);
return NULL;
}
memcpy(n->data, data, sz);
n->prev = NULL;
n->next = NULL;
return n;
}
static int List_Push(pList l, int pos, void *data, size_t sz)
{
assert( l != NULL);
assert(data != NULL);
assert(sz == l->sz);
assert(pos >= 0 && pos <= l->num);
pListNode iter = l->head;
pListNode tmp;
int idx;
if(pos<0 || pos>l->num)
return -1;
pListNode n = List_NewNode(data, sz);
if(n == NULL)
return -2;
//no list member, new node to be head and tail
if(l->num == 0){
l->head = n;
l->tail = n;
l->num++;
return 0;
}
//insert the front
if(pos == 0){
n->next = l->head;
n->prev = NULL;
l->head->prev = n;
l->head = n;
}else{
//insert the tail
if(pos == l->num)
{
n->next = NULL;
n->prev = l->tail;
l->tail->next = n;
l->tail = n;
}
else
{
for(idx=0; idx<pos-1; idx++)
iter = iter->next;
tmp = iter->next;
iter->next = n;
n->next = tmp;
n->prev = iter;
tmp->prev = n;
}
}
l->num++;
return 0;
}
static int List_PushFront(pList l, void *data, size_t sz)
{
return List_Push(l, 0, data, sz);
}
static int List_PushBack(pList l, void *data, size_t sz)
{
return List_Push(l, l->num, data, sz);
}
static int List_Pop(pList l, int pos)
{
assert( l != NULL);
assert( pos >0 && pos <= l->num);
pListNode tmp;
pListNode iter = l->head;
int idx;
for(idx=1; idx<pos; idx++)
iter = iter->next;
//move the front
if(iter == l->head){
if(l->num == 1){
assert( l->head == l->tail);
free(l->head->data);
free(l->head);
l->head = NULL;
l->tail = NULL;
}else{
tmp= l->head;
l->head = l->head->next;
l->head->prev = NULL;
tmp->next = NULL;
tmp->prev = NULL;
free(tmp->data);
free(tmp);
}
}
//move the tail
else if(iter == l->tail)
{
tmp = l->tail;
if(l->num == 1){
assert(l->tail == l->head);
free(l->tail->data);
free(l->tail);
l->tail = l->head = NULL;
}else{
l->tail = l->tail->prev;
l->tail->next = NULL;
tmp->prev = tmp->next = NULL;
free(tmp->data);
free(tmp);
}
}
//move the middle one
else
{
iter->prev->next = iter->next;
iter->next->prev = iter->prev;
iter->next = iter->prev = NULL;
free(iter->data);
free(iter);
}
l->num--;
return 0;
}
static int List_PopFront(pList l)
{
return List_Pop(l, 1);
}
static int List_PopBack(pList l)
{
return List_Pop(l, l->num);
}
static void List_Show(pList l)
{
if( l == NULL )
return;
printf("list, total member: %d\n", l->num);
pListNode iter = l->head;
if(l->show != NULL)
{
while(iter != NULL)
{
l->show(iter->data);
iter = iter->next;
}
}
printf("\n");
}
static pListNode List_Find(pList l, void *data, size_t sz)
{
assert(l != NULL && data != NULL && sz == l->sz);
if(l->cmpFun == NULL)
return -1;
pListNode iter = l->head;
while(iter != NULL)
{
if(l->cmpFun(data, iter->data) == 0){
break;
}
iter = iter->next;
}
return iter;
}
pListNode List_Begin(pList l)
{
assert(l != NULL);
return l->head;
}
pListNode List_End(pList l)
{
assert(l != NULL);
return l->tail;
}
int List_Size(pList l)
{
assert(l != NULL);
return l->num;
}
pList ListCreate(int datasize, NodeCmpFun cmpFun, ShowDataFun show)
{
pList this = (pList)malloc(sizeof(List));
if(this == NULL){
perror("malloc\n");
return NULL;
}
//private data
this->head = NULL;
this->tail = NULL;
this->num = 0;
this->sz = datasize;
this->cmpFun = cmpFun;
this->show = show;
//operation
this->push = List_Push;
this->push_front = List_PushFront;
this->push_back = List_PushBack;
this->pop = List_Pop;
this->pop_front = List_PopFront;
this->pop_back = List_PopBack;
this->find = List_Find;
this->show_list = List_Show;
this->begin = List_Begin;
this->end = List_End;
this->size = List_Size;
}
int ListDelete(pList l)
{
assert(l != NULL);
pListNode iter = l->head;
while(iter != NULL)
{
l->pop_front(l);
iter = l->head;
}
assert(l->num == 0);
free(l); l = NULL;
return 0;
}
"main.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myList.h"
void ShowData(void *data)
{
if(data == NULL)
return;
int *p = (int *)data;
printf("%d\n", *p);
}
int IntCmpFun(void *s1, void *s2)
{
int *p1 = (int *)s1;
int *p2 = (int *)s2;
if(*p1 == *p2){
return 0;
}else if(*p1 > *p2){
return 1;
}else{
return -1;
}
}
int main()
{
int data[] = {1, 2, 3, 4, 5, 6, 7, 8};
int num = sizeof(data)/sizeof(int);
int idx;
int tmp;
pList l = ListCreate(sizeof(int), IntCmpFun, ShowData);
if(l == NULL)
exit(-1);
for(idx=0; idx<num; idx++)
l->push_front(l, data+idx, sizeof(int));
l->show_list(l);
for(idx=4; idx<num; idx++)
l->push_back(l, data+idx, sizeof(int));
l->show_list(l);
for(idx=0; idx<num-4; idx++)
l->push_front(l, data+idx, sizeof(int));
l->show_list(l);
l->pop_back(l);
l->show_list(l);
l->pop_front(l);
l->show_list(l);
pListNode iter_b = l->begin(l);
ShowData(iter_b->data);
pListNode iter_e = l->end(l);
ShowData(iter_e->data);
tmp = 88;
l->push(l, 14, &tmp, sizeof(tmp));
tmp = 99;
l->push(l, 14, &tmp, sizeof(tmp));
l->show_list(l);
l->pop(l, 15);
l->show_list(l);
tmp = 98;
pListNode iter_f = l->find(l, &tmp, sizeof(int));
if(iter_f == NULL){
printf("%d not found!\n", tmp);
}else{
printf("found %d\n", *(int *)iter_f->data);
}
ListDelete(l);
return 0;
}