//数据结构C语言双向链表实现
#ifndef __LIST_H__
#define __LIST_H__
#include <stdlib.h>
#define LIST_ITER_FORWARD 0
#define LIST_ITER_REVERSE 1
#define ListHead(l) ((l)->head)
#define ListTail(l) ((l)->tail)
#define ListLength(l) ((l)->length)
#define ListIsEmpty(l) (ListLength(l)==0)
#define ListPrevNode(n) ((n)->prev)
#define ListNextNode(n) ((n)->next)
#define ListNodeValue(n) ((n)->value)
#define ListSetCopy(l,f) ((l)->copy = (f))
#define ListSetFree(l,f) ((l)->free = (f))
#define ListSetMatch(l,f) ((l)->match = (f))
#define ListSetCompare(l,f) ((l)->compare = (f))
#define ListGetCopy(l) ((l)->copy)
#define ListGetFree(l) ((l)->free)
#define ListGetMatch(l) ((l)->match)
#define ListGetCompare(l) ((l)->compare)
typedef struct ListNode
{
struct ListNode * prev;
struct ListNode * next;
void * value;
}ListNode;
typedef struct List
{
struct ListNode * head;
struct ListNode * tail;
unsigned long length;
void *(*copy)(void * value);
void (*free)(void ** value);
int (*match)(void * value, void * key);
int (*compare)(void * value1, void * value2);
}List;
typedef struct ListIter
{
struct ListNode * node;
int direction;
}ListIter;
List * ListCreate(void);
void ListRelease(List ** list); //O(n)
void ListClear(List * list); //O(n)
List * ListPushFront(List * list, void * value); //O(1)
List * ListPushBack(List * list, void * value); //O(1)
ListIter ListGetIterator(List * list, int direction);
ListNode * ListNext(ListIter * iter); //O(1)
ListNode * ListIndex(List * list, int index); //O(n)
ListNode * ListSearchNode(List * list, void * key); //O(n)
List * ListInsertNode(List * list, ListNode * oldnode, void * value, int after); //O(1)
void ListDeleteNode(List * list, ListNode * oldnode); //O(1)
List * ListMerge(List * l, List * o); //O(1)
List * ListRotate(List * list); //O(1)
List * ListReverse(List * list); //O(n)
List * ListCopy(List * list); //O(n)
List * ListSort(List * list); //O(n)~O(n2)
void ListSwap(List * l, List * o); //O(1)
#endif
#include "List.h"
List * ListCreate(void)
{
List * list = (List*)malloc(sizeof(List));
if (!list) return NULL;
list->head = list->tail = NULL;
list->copy = NULL;
list->free = NULL;
list->match = NULL;
list->compare = NULL;
list->length = 0;
return list;
}
void ListRelease(List ** list)
{
if (*list)
{
ListClear(*list);
free(*list);
*list = NULL;
}
return;
}
void ListClear(List * list)
{
ListNode * current = list->head;
ListNode * next = NULL;
while (current)
{
next = current->next;
if (list->free) list->free(¤t->value);
free(current);
current = next;
}
list->head = list->tail = NULL;
list->length = 0;
return;
}
List * ListPushFront(List * list, void * value)
{
ListNode * node = (ListNode*)malloc(sizeof(ListNode));
if (!node) return NULL;
node->value = value;
if (list->length == 0)
{
node->prev = node->next = NULL;
list->head = list->tail = node;
}
else
{
node->prev = NULL;
node->next = list->head;
list->head->prev = node;
list->head = node;
}
list->length++;
return list;
}
List * ListPushBack(List * list, void * value)
{
ListNode * node = (ListNode*)malloc(sizeof(ListNode));
if (!node) return NULL;
node->value = value;
if (list->length == 0)
{
node->prev = node->next = NULL;
list->head = list->tail = node;
}
else
{
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->length++;
return list;
}
ListIter ListGetIterator(List * list, int direction)
{
ListIter iter;
if (direction == LIST_ITER_FORWARD)
{
iter.node = list->head;
iter.direction = direction;
}
else
{
iter.node = list->tail;
iter.direction = direction;
}
return iter;
}
ListNode * ListNext(ListIter * iter)
{
ListNode * current = iter->node;
if (current)
{
if (iter->direction == LIST_ITER_FORWARD)
{
iter->node = current->next;
}
else
{
iter->node = current->prev;
}
}
return current;
}
ListNode * ListSearchNode(List * list, void * key)
{
ListIter iter = ListGetIterator(list,LIST_ITER_FORWARD);
ListNode * node = NULL;
while((node = ListNext(&iter)) != NULL)
{
if (list->match)
{
if (list->match(node->value, key))
{
return node;
}
}
else
{
if (node->value == key)
{
return node;
}
}
}
return NULL;
}
ListNode * ListIndex(List * list, int index)
{
ListNode * current = NULL;
if (index >= 0)
{
current = list->head;
while(index-- && current)
{
current = current->next;
}
}
else
{
current = list->tail;
index = (-index)-1;
while(index-- && current)
{
current = current->prev;
}
}
return current;
}
List * ListInsertNode(List * list, ListNode * oldnode, void * value, int after)
{
ListNode * node = (ListNode*)malloc(sizeof(ListNode));
if (!node) return NULL;
node->value = value;
if (after)
{
node->prev = oldnode;
node->next = oldnode->next;
if (list->tail == oldnode)
{
list->tail = node;
}
}
else
{
node->prev = oldnode->prev;
node->next = oldnode;
if (list->head == oldnode)
{
list->head = node;
}
}
if (node->prev)
{
node->prev->next = node;
}
if (node->next)
{
node->next->prev = node;
}
list->length++;
return list;
}
void ListDeleteNode(List * list, ListNode * node)
{
if (node->prev)
{
node->prev->next = node->next;
}
else
{
list->head = node->next;
}
if (node->next)
{
node->next->prev = node->prev;
}
else
{
list->tail = node->prev;
}
if (list->free) list->free(&node->value);
free(node);
list->length--;
return;
}
List * ListMerge(List * l, List * o)
{
if (!o->tail)
{
return l;
}
if (!l->tail)
{
l->head = o->head;
l->tail = o->tail;
l->length = o->length;
return l;
}
l->tail->next = o->head;
o->head->prev = l->tail;
l->tail = o->tail;
l->length += o->length;
o->head = o->tail = NULL;
o->length = 0;
return l;
}
List * ListRotate(List * list)
{
ListNode * tail = list->tail;
if (ListLength(list) <= 1) return list;
list->tail = tail->prev;
list->tail->next = NULL;
list->head->prev = tail;
tail->prev = NULL;
tail->next = list->head;
list->head = tail;
return list;
}
List * ListReverse(List * list)
{
if (ListLength(list) <= 1)
{
return list;
}
ListNode * current = list->head;
ListNode * next = NULL;
ListNode * tmp = NULL;
while(current)
{
next = current->next;
tmp = current->prev;
current->prev = current->next;
current->next = tmp;
current = next;
}
tmp = list->head;
list->head = list->tail;
list->tail = tmp;
return list;
}
List * ListCopy(List * list)
{
List * copy = ListCreate();
if (copy == NULL) return NULL;
copy->copy = list->copy;
copy->free = list->free;
copy->match = list->match;
copy->compare = list->compare;
ListNode * current = NULL;
ListIter iter = ListGetIterator(list, LIST_ITER_FORWARD);
while ((current = ListNext(&iter)) != NULL)
{
void * value;
if (copy->copy)
{
value = copy->copy(current->value);
if (!value)
{
ListRelease(©);
return NULL;
}
}
else
{
value = current->value;
}
if (ListPushBack(copy,value) == NULL)
{
ListRelease(©);
return NULL;
}
}
return copy;
}
List * ListSort(List * list)
{
void * tmp = NULL;
int n = list->length;
for (int j=0; j<n-1; j++)
{
for (int i=0; i<n-j-1; i++)
{
ListNode * n1 = ListIndex(list,i);
ListNode * n2 = ListIndex(list,i+1);
if (list->compare)
{
if (list->compare(n1->value, n2->value) > 0)
{
tmp = n1->value;
n1->value = n2->value;
n2->value = tmp;
}
}
else
{
if (n1->value > n2->value)
{
tmp = n1->value;
n1->value = n2->value;
n2->value = tmp;
}
}
}
}
return list;
}
void ListSwap(List * l, List * o)
{
ListNode * head = l->head;
ListNode * tail = l->tail;
int length = l->length;
void *(*pcopy)(void * value) = l->copy;
void (*free)(void ** value) = l->free;
int (*match)(void * value, void * key) = l->match;
int (*compare)(void * value1, void * value2) = l->compare;
l->head = o->head;
l->tail = o->tail;
l->length = o->length;
l->copy = o->copy;
l->free = o->free;
l->match = o->match;
l->compare = o->compare;
o->head = head;
o->tail = tail;
o->length = length;
o->copy = pcopy;
o->free = free;
o->match = match;
o->compare = compare;
}
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include "List.h"
typedef struct USER
{
char usrname[20];
char password[20];
int type;
}USER;
void UserInit(USER * usr, const char * name, const char* pwd, int type)
{
memset(usr, 0, sizeof(USER));
memcpy(usr->usrname, name, strlen(name));
memcpy(usr->password, pwd, strlen(pwd));
usr->type = type;
}
void UserFree(void ** value)
{
delete(*value);
*value = NULL;
}
void * UserCopy(void * value)
{
USER * usr = (USER*)value;
USER * copy = new USER();
UserInit(copy, usr->usrname, usr->password, usr->type);
return copy;
}
int UserMatch(void * value, void * key)
{
USER *pvalue = (USER*)value;
USER *pkey = (USER*)key;
if (strcmp(pvalue->usrname,pkey->usrname) == 0)
{
return 1;
}
else
{
return 0;
}
}
int UserCompare(void * value1, void * value2)
{
USER *pvalue1 = (USER*)value1;
USER *pvalue2 = (USER*)value2;
if (strcmp(pvalue1->usrname,pvalue2->usrname) > 0)
{
return 1;
}
else if (strcmp(pvalue1->usrname,pvalue2->usrname) < 0)
{
return -1;
}
else
{
return 0;
}
}
int main(int argc, char* argv[])
{
int count1 = 100000;
while(count1--)
{
USER *usr1 = new USER();
UserInit(usr1, "1_zhang", "zhang_1", 1);
USER *usr2 = new USER();
UserInit(usr2, "2_wang", "wang_2", 2);
USER *usr3 = new USER();
UserInit(usr3, "3_li", "li_3", 3);
USER *usr4 = new USER();
UserInit(usr4, "4_zhao", "zhao_4", 4);
List * list1 = ListCreate();
List * list2 = ListCreate();
ListIter iter;
ListNode * n;
ListSetFree(list1, UserFree);
ListSetCopy(list1, UserCopy);
ListSetMatch(list1, UserMatch);
ListSetCompare(list1, UserCompare);
ListSetFree(list2, UserFree);
ListSetCopy(list2, UserCopy);
ListSetMatch(list2, UserMatch);
ListSetCompare(list2, UserCompare);
ListPushBack(list1, usr1);
ListPushBack(list1, usr3);
ListPushBack(list2, usr2);
ListPushBack(list2, usr4);
ListSwap(list1,list2);
ListMerge(list1,list2);
iter = ListGetIterator(list1, LIST_ITER_FORWARD);
while((n = ListNext(&iter)) != NULL)
{
USER *usr = (USER *)n->value;
printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
}
ListSort(list1);
ListReverse(list1);
iter = ListGetIterator(list1, LIST_ITER_FORWARD);
while((n = ListNext(&iter)) != NULL)
{
USER *usr = (USER *)n->value;
printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
}
USER *usr5 = new USER();
UserInit(usr5, "4_zhao", "zhao_5", 5);
ListNode * node4 = ListSearchNode(list1, usr5);
if (node4)
{
USER *usr = (USER *)node4->value;
printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
}
delete usr5;
List * list3 = ListCopy(list1);
iter = ListGetIterator(list3, LIST_ITER_FORWARD);
while((n = ListNext(&iter)) != NULL)
{
USER *usr = (USER *)n->value;
printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
}
while (!ListIsEmpty(list3))
{
ListNode * curnode = ListTail(list3);
USER * usr = (USER *)curnode->value;
ListDeleteNode(list3, curnode);
}
ListRelease(&list3);
ListRelease(&list1);
ListRelease(&list2);
}
return 0;
}