自己写的LinkList

来源:互联网 发布:备案域名便宜 编辑:程序博客网 时间:2024/06/05 06:47
Source FILE: CAlgCommon.h
#ifndef _C_ALG_COMMON_H_#define _C_ALG_COMMON_H_#include <string.h>#include <stdlib.h>#ifndef __cplusplus#define inline __inline#endif#ifdef __cplusplusextern "C" {#endiftypedef enum {CALG_ENUM_NEXT = 0,CALG_ENUM_REPEAT ,CALG_ENUM_STOP }CAlgEnum;typedef CAlgEnum (*Alg_IteRator_F)(void* elem);typedef int (*Alg_Cmp_F)(const void* left, const void* right, unsigned int size);#ifdef __cplusplus}#endif#endif//end of file
Source File: CAlgList.h
#ifndef _C_ALG_LIST_H_#define _C_ALG_LIST_H_#include <string.h>#include <stdlib.h>#include "CAlgCommon.h"#ifdef __cplusplusextern "C" {#endiftypedef struct _CAlgNode{void * curr_data;
struct _CAlgNode * prev;
struct _CAlgNode * next;
}CAlgNode;
typedef struct {
CAlgNode* head;
CAlgNode* tail;
int elem_count;
unsigned int elem_size;
}CAlgList;
static inline void CAlgList_ReSet(CAlgList* l, unsigned int elem_size)
{
l->head = l->tail = NULL;
l->elem_count = 0;
l->elem_size = elem_size;
}
static inline void CAlgList_Insert(CAlgList* l, CAlgNode* prev, CAlgNode* n)
{
n->prev = prev;
if(prev)
{
n->next = prev->next;
prev->next = n;
}
else
{
n->next = l->head;
l->head = n;
}
if(n->next)
n->next->prev = n;
if(prev == l->tail)
l->tail = n;
l->elem_count ++;
}
static inline CAlgNode* CAlgList_AddHead(CAlgList* l, CAlgNode* n)
{
CAlgList_Insert(l, NULL, n);
return l->head;
}
static inline CAlgNode* CAlgList_AddTail(CAlgList* l, CAlgNode* n)
{
CAlgList_Insert(l, l->tail, n);
return l->tail;
}
static inline CAlgNode* CAlgList_Find(CAlgList* l, void* data, Alg_Cmp_F node_cmp)
{
CAlgNode* tmp = l->head;
if(node_cmp == NULL)
node_cmp = memcmp;
while(tmp)
{
if(0 == node_cmp(tmp->curr_data, data, l->elem_size))
return tmp;
tmp = tmp->next;
}
return NULL;
}
static inline int CAlgList_RemoveNode(CAlgList* l, CAlgNode* n)
{
if( NULL == n) return -1;
if(n == l->head)
l->head = l->head->next;
if(n == l->tail)
l->tail = l->tail->prev;
if(n->prev)
n->prev->next = n->next;
if(n->next)
n->next->prev = n->prev;
if(n)
l->elem_count --;
return 0;
}
static inline CAlgNode* CAlgList_RemoveHead(CAlgList* l)
{
CAlgNode* head = l->head;
CAlgList_RemoveNode(l, l->head);
return head;
}
static inline CAlgNode* CAlgList_RemoveTail(CAlgList* l)
{
CAlgNode* tail = l->tail;
CAlgList_RemoveNode(l, l->tail);
return tail;
}
#define ALGLIST_FOREACH(alglist, node) do{\
node = alglist->head;\
for(; NULL != node; node=node->next){
#define ALGLIST_FOREACH_END() }}while(0);
static inline int CAlgList_Enum(const CAlgList* l, Alg_IteRator_F it, int reverse)
{
int count = 0u;
CAlgNode* tmp ;
CAlgEnum rc ;
if(reverse)
tmp = l->tail;
else
tmp = l->head;
while(tmp)
{
count ++;
rc = it(tmp->curr_data);
if(rc == CALG_ENUM_REPEAT)
continue;
else if(rc == CALG_ENUM_STOP)
return count;
if(reverse)
tmp = tmp->prev;
else
tmp = tmp->next;
}
return count;
}
#ifdef __cplusplus
}
#endif
#endif//end of file
单元测试:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include "CAlgList.h"typedef struct {int a;int b;}CAlgListNodeData;#define MAX_NODE_ELEM   10000000static CAlgListNodeData* g_NodeDataPool = NULL;static CAlgNode* g_CAlgNodes = NULL;static CAlgList* g_CAlgList = NULL;extern "C" CAlgEnum TestAlgList_Enum(void* elem){CAlgListNodeData* e = (CAlgListNodeData*)elem;printf("%5d, a=%5d, b=%5d\n", e - g_NodeDataPool, e->a, e->b);return CALG_ENUM_NEXT;}extern "C" CAlgEnum TestAlgList_EnumNothing(void* elem){return CALG_ENUM_NEXT;}extern "C" static int TestAlgList_node_cmp(const void* left, const void* right, unsigned int size){CAlgListNodeData* l, *r;l = (CAlgListNodeData*)left;r = (CAlgListNodeData*)right;if (l->a != r->a) return l->a - r->a;return l->b - r->b;}void TestAlgList_Init(){g_NodeDataPool = (CAlgListNodeData*)malloc(sizeof(CAlgListNodeData)*MAX_NODE_ELEM);g_CAlgNodes = (CAlgNode*)malloc(sizeof(CAlgNode)*MAX_NODE_ELEM);g_CAlgList = (CAlgList*)malloc(sizeof(CAlgList));CAlgList_ReSet(g_CAlgList, sizeof(CAlgListNodeData));}void TestAlgList_Free(){free(g_NodeDataPool);g_NodeDataPool = NULL;free(g_CAlgNodes);g_CAlgNodes = NULL;free(g_CAlgList);g_CAlgList = NULL;}void TestAlgList_AddAll_Pointer(int add_tail){CAlgNode* n = g_CAlgNodes;CAlgListNodeData* d = g_NodeDataPool;int i;for(i=0; i<MAX_NODE_ELEM; i++){d->a = i+1;d->b = i+2;n[i].curr_data = (void*)d;if(add_tail)CAlgList_AddTail(g_CAlgList, &n[i]);elseCAlgList_AddHead(g_CAlgList, &n[i]);d++;assert(g_CAlgList->elem_count == i +1);}i=0;n = g_CAlgList->head;do{if(n == g_CAlgList->head){assert(n->prev == NULL);}if(n == g_CAlgList->tail){assert(n->next == NULL);}d = (CAlgListNodeData*)n->curr_data;if(add_tail){assert(d->a == i+1);assert(d->b == i+2);}else{assert(d->a == MAX_NODE_ELEM - i);assert(d->b == MAX_NODE_ELEM - i +1);}i++;}while(n=n->next);assert(i == MAX_NODE_ELEM);assert(g_CAlgList->elem_count == MAX_NODE_ELEM);}void TestAlgList_RemoveHead(){CAlgNode* n = g_CAlgNodes;CAlgListNodeData* d;int i;for(i=0; i<MAX_NODE_ELEM; i++){n = CAlgList_RemoveHead( g_CAlgList);d = (CAlgListNodeData*)n->curr_data;assert(d->a == i+1);assert(d->b == i+2);assert(g_CAlgList->elem_count == MAX_NODE_ELEM - i -1);}assert(g_CAlgList->head == NULL);assert(g_CAlgList->tail == NULL);}void TestAlgList_RemoveTail(){CAlgNode* n = g_CAlgNodes;CAlgListNodeData* d;int i;for(i=0; i<MAX_NODE_ELEM; i++){n = CAlgList_RemoveTail( g_CAlgList);d = (CAlgListNodeData*)n->curr_data;assert(d->a == i+1);assert(d->b == i+2);assert(g_CAlgList->elem_count == MAX_NODE_ELEM - i - 1);}assert(g_CAlgList->head == NULL);assert(g_CAlgList->tail == NULL);}void TestAlgList_Insert_Remove(){const int node_num = 10;CAlgNode* n = g_CAlgNodes;CAlgListNodeData* d = g_NodeDataPool;int i;CAlgListNodeData tmp;//list empty find failfor(i=0; i<node_num/2; i++){d = &g_NodeDataPool[node_num/2+i];tmp.a = i+1;tmp.b = i+2;n = CAlgList_Find(g_CAlgList, &tmp, TestAlgList_node_cmp);assert(n == NULL);}//list empty remove failassert (NULL == CAlgList_RemoveTail( g_CAlgList));assert (NULL == CAlgList_RemoveHead( g_CAlgList));assert (g_CAlgList->elem_count == 0);//add node_num/2 nodesfor(i=0; i<node_num/2; i++){d = &g_NodeDataPool[i];d->a = i+1;d->b = i+2;g_CAlgNodes[i].curr_data = (void*)d;CAlgList_AddTail( g_CAlgList, &g_CAlgNodes[i]);assert(g_CAlgList->elem_count == i +1);}assert(g_CAlgList->elem_count == node_num/2);printf("add 5 nodes using CAlgList_AddTail()\n");CAlgList_Enum(g_CAlgList,TestAlgList_Enum,0);//insert node_num/2 nodes into the list//1,      2,      3,      4,      5 //1,1001, 2,1002, 3,1003, 4,1004, 5,1005for(i=0; i<node_num/2; i++){d = &g_NodeDataPool[node_num/2+i];tmp.a = i+1;tmp.b = i+2;n = CAlgList_Find( g_CAlgList, &tmp, TestAlgList_node_cmp);assert(n != NULL);d->a = 1000+i+1;d->b = 2000+i+1;g_CAlgNodes[node_num/2+i].curr_data = d;CAlgList_Insert(g_CAlgList, n, &g_CAlgNodes[node_num/2+i]);}printf("\nafter add 5 nodes using CAlgList_Insert()\n");CAlgList_Enum(g_CAlgList,TestAlgList_Enum,0);i=0;n = g_CAlgList->head;do{if(n == g_CAlgList->head){assert(n->prev == NULL);}if(n == g_CAlgList->tail){assert(n->next == NULL);}d = (CAlgListNodeData*)n->curr_data;if((i % 2) == 0){assert(d->a == i/2+1);assert(d->b == i/2+2);}else{assert(d->a == 1000+i/2+1);assert(d->b == 2000+i/2+1);}i++;}while(n=n->next);assert(i == node_num);assert(g_CAlgList->elem_count == node_num);//remove node 1001,1002,1003,1004,1005//before 1,1001, 2,1002, 3,1003, 4,1004, 5,1005//after  1,      2,      3,      4,      5 for(i=0; i<node_num/2; i++){tmp.a = 1000+i+1;tmp.b = 2000+i+1;n = CAlgList_Find( g_CAlgList, &tmp, TestAlgList_node_cmp);assert(n != NULL);assert(0 == CAlgList_RemoveNode( g_CAlgList, n));}printf("\nafter remove 5 nodes using CAlgList_RemoveNode\n");CAlgList_Enum(g_CAlgList,TestAlgList_Enum,0);assert(g_CAlgList->elem_count == node_num/2);i=0;n = g_CAlgList->head;do{if(n == g_CAlgList->head){assert(n->prev == NULL);}if(n == g_CAlgList->tail){assert(n->next == NULL);}d = (CAlgListNodeData*)n->curr_data;assert(d->a == i+1);assert(d->b == i+2);i++;}while(n=n->next);//remove head 1//after  2,      3,      4,      5 n = CAlgList_RemoveHead( g_CAlgList);assert(n != NULL && g_CAlgList->elem_count > 2);d = (CAlgListNodeData*)n->curr_data;assert(d->a == 1);assert(d->b == 2);//remove tail 5//after  2,      3,      4,      n = CAlgList_RemoveTail( g_CAlgList);assert(n != NULL && g_CAlgList->elem_count > 2);d = (CAlgListNodeData*)n->curr_data;assert(d->a == 5);assert(d->b == 6);assert(g_CAlgList->elem_count == 3);i=1;n = g_CAlgList->head;do{if(n == g_CAlgList->head){assert(n->prev == NULL);}if(n == g_CAlgList->tail){assert(n->next == NULL);}d = (CAlgListNodeData*)n->curr_data;assert(d->a == i+1);assert(d->b == i+2);i++;}while(n=n->next);assert(i == 4);printf("\nafter CAlgList_RemoveHead && CAlgList_RemoveTail\n");CAlgList_Enum(g_CAlgList,TestAlgList_Enum,0);//remove allwhile(CAlgList_RemoveHead( g_CAlgList))printf("remove...\n");assert(g_CAlgList->elem_count == 0);}#include <Windows.h>void TestAlgList_Run(){SYSTEMTIME st1, st2;FILETIME ft1, ft2; //100nsCAlgNode* n;int i;TestAlgList_Init();//test add headGetLocalTime(&st1);TestAlgList_AddAll_Pointer(1);GetLocalTime(&st2);SystemTimeToFileTime(&st1, &ft1);SystemTimeToFileTime(&st2, &ft2);printf("%s using %u.%03ums to add head %d nodes %02u:%02u:%02u.%03u - %02u:%02u:%02u.%03u\n", __FILE__,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10000,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10, MAX_NODE_ELEM,st1.wHour,st1.wMinute,st1.wSecond,st1.wMilliseconds,st2.wHour,st2.wMinute,st2.wSecond,st2.wMilliseconds);//iterate all elementsGetLocalTime(&st1);CAlgList_Enum(g_CAlgList,TestAlgList_EnumNothing,0);GetLocalTime(&st2);SystemTimeToFileTime(&st1, &ft1);SystemTimeToFileTime(&st2, &ft2);printf("%s using %u.%03ums to iterate %d nodes %02u:%02u:%02u.%03u - %02u:%02u:%02u.%03u\n", __FILE__,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10000,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10, MAX_NODE_ELEM,st1.wHour,st1.wMinute,st1.wSecond,st1.wMilliseconds,st2.wHour,st2.wMinute,st2.wSecond,st2.wMilliseconds);i=0;GetLocalTime(&st1);ALGLIST_FOREACH(g_CAlgList, n);i++;ALGLIST_FOREACH_END();GetLocalTime(&st2);SystemTimeToFileTime(&st1, &ft1);SystemTimeToFileTime(&st2, &ft2);printf("%s using %u.%03ums to iterate %d nodes %02u:%02u:%02u.%03u - %02u:%02u:%02u.%03u\n", __FILE__,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10000,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10, i,st1.wHour,st1.wMinute,st1.wSecond,st1.wMilliseconds,st2.wHour,st2.wMinute,st2.wSecond,st2.wMilliseconds);//CAlgList_Enum(CAlgList_GetAlgFunc(),g_CAlgList,TestAlgList_Enum,0);//remove all TestAlgList_RemoveHead();//test add tailGetLocalTime(&st1);TestAlgList_AddAll_Pointer(0);GetLocalTime(&st2);SystemTimeToFileTime(&st1, &ft1);SystemTimeToFileTime(&st2, &ft2);printf("%s using %u.%03ums to add tail %d nodes %02u:%02u:%02u.%03u - %02u:%02u:%02u.%03u\n", __FILE__,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10000,(ft2.dwLowDateTime-ft1.dwLowDateTime)/10, MAX_NODE_ELEM,st1.wHour,st1.wMinute,st1.wSecond,st1.wMilliseconds,st2.wHour,st2.wMinute,st2.wSecond,st2.wMilliseconds);//CAlgList_Enum(CAlgList_GetAlgFunc(),g_CAlgList,TestAlgList_Enum,1);TestAlgList_RemoveTail();//test find and insertCAlgList_ReSet(g_CAlgList, sizeof(CAlgListNodeData));TestAlgList_Insert_Remove();TestAlgList_Free();}
0 0
原创粉丝点击