实现插入自动排序的双向链表,插入的的每个元素是唯一且是排序好的,从链表头到链表尾部都是按照从小到大的顺序的
ds.h如下:
/************************************************************************* > File Name: ds.h > Author: zhoulin > Mail: 715169549@qq.com > Created Time: Thu 31 Dec 2015 07:16:49 PM EST ***********************************************************************/ /*********************************************************************** * define listNode 、list struct ***********************************************************************/ #ifndef __ds_h #define __ds_h typedef struct listNode //双向变脸的节点定义 { int var; struct listNode *prev; struct listNode *next; }listNode; typedef struct list { unsigned int len; //链表的长度 struct listNode *head; //链表的头部节点 struct listNode *tail; //链表的尾部节点 }list; #define listNodeHead(l) ((l)->head) #define listNodeTail(l) ((l)->tail) #define listNodeLen(l) ((l)->len) #define listNodePrev(l) ((l)->prev) #define listNodeNext(l) ((l)->next) #define listNodeNull(n) { (n)->prev = NULL; (n)->next = NULL; } /********************************************************************** * operation of struct listNode and list * ********************************************************************/ list *listCreate(); //链表创建 int listNodeAdd(list *lt, listNode *value); //添加listNode到链表 int listNodeDel(list *lt, int var); //删除某个链表 listNode *listNodeQuery(list *lt, int var); //查询某个链表 void listNodePrt(list *lt); //打印整个链表 int listNodeRelease(list *lt); //销毁整个链表 #endif
ds_pt.c代码如下:
/************************************************************************* > File Name: ds_pt.c > Author: zhoulin > Mail: 715169549@qq.com > Created Time: Thu 31 Dec 2015 07:33:04 PM EST ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include "ds.h" list *listCreate() { list *lt = NULL; if((lt = (list *)malloc(sizeof(*lt))) != NULL) { listNodeLen(lt) = 0; listNodeHead(lt) = NULL; listNodeTail(lt) = NULL; } return lt; } int listNodeAdd(list *lt, listNode *value) { if(lt == NULL || value == NULL) { return -1; } if(listNodeLen(lt) == 0) { listNodeHead(lt) = listNodeTail(lt) = value; __sync_fetch_and_add(&(lt->len),1); return 0; } listNode *pHead = listNodeHead(lt); listNode *pTail = listNodeTail(lt); if(listNodeLen(lt) == 1) { if(pHead->var == value->var){ return -1; } if(pHead->var > value->var) { listNodeHead(lt) = value; listNodeNext(value) = pHead; listNodePrev(pHead) = value; __sync_fetch_and_add(&(lt->len),1); return 0; } listNodeTail(lt) = listNodeTail(lt) = value; listNodePrev(value) = pHead; listNodeNext(pHead) = value; __sync_fetch_and_add(&(lt->len),1); return 0; } listNode *pCur = pHead; while(pCur != NULL){ if(pCur->var == value->var){ return -1; } listNode *pNext=listNodeNext(pCur); listNode *pPrev=listNodePrev(pCur); if(pPrev == NULL && pNext != NULL) { //head if(pCur->var > value->var) { listNodeHead(lt) = value; listNodeNext(value) = pCur; listNodePrev(pCur) = value; __sync_fetch_and_add(&(lt->len),1); break; } if(pCur->var < value->var && pNext->var> value->var) { listNodePrev(value) = pCur; listNodeNext(value) = pNext; listNodePrev(pNext) = listNodeNext(pCur) = value; __sync_fetch_and_add(&(lt->len),1); break; } } if(pPrev != NULL && pNext != NULL) { //mid if(pCur->var < value->var && pNext->var > value->var) { listNodePrev(value) = pCur; listNodeNext(value) = pNext; listNodePrev(pNext) = listNodeNext(pCur) = value; __sync_fetch_and_add(&(lt->len),1); break; } if(pCur->var > value->var && pPrev->var < value->var) { listNodePrev(pCur) = value; listNodeNext(pPrev) = value; listNodePrev(value) = pPrev; listNodeNext(value) = pCur; __sync_fetch_and_add(&(lt->len),1); break; } } if(pPrev != NULL && pNext == NULL) { //tail listNode if(pCur->var < value->var) { listNodeTail(lt) = value; listNodePrev(value) =pCur; listNodeNext(pCur) = value; __sync_fetch_and_add(&(lt->len),1); break; } if(pCur->var > value->var && pPrev->var < value->var) { listNodeNext(value) = pCur; listNodePrev(value) = pPrev; listNodePrev(pCur) = value; listNodeNext(pPrev) = value; __sync_fetch_and_add(&(lt->len),1); break; } } pCur = listNodeNext(pCur); } return 0; } int listNodeDel(list *lt, int var) { if(lt == NULL) { return -1; } listNode *pHead = listNodeHead(lt); listNode *pTail = listNodeTail(lt); if(pHead != NULL && pTail != NULL) { if(pHead->var > var || pTail->var < var){ return -1; } } listNode *pCur = pHead; while(pCur != NULL) { listNode *pNext = listNodeNext(pCur); listNode *pPrev = listNodePrev(pCur); if(pCur->var == var) { if(pPrev == NULL && pNext != NULL){ listNodeHead(lt) = pNext; listNodePrev(pNext) = NULL; __sync_fetch_and_sub(&(lt->len),1); listNodeNull(pCur); free(pCur); pCur = NULL; return 0; } if(pPrev != NULL && pNext != NULL){ listNodePrev(pNext) = pPrev; listNodeNext(pPrev) = pNext; __sync_fetch_and_sub(&(lt->len),1); listNodeNull(pCur); pCur = NULL; return 0; } if(pPrev != NULL && pNext == NULL){ listNodeTail(lt) = pPrev; listNodeNext(pPrev) = NULL; __sync_fetch_and_sub(&(lt->len),1); listNodeNull(pCur); free(pCur); pCur=NULL; return 0; } } pCur =listNodeNext(pCur); } return -1; } listNode *listNodeQuery(list *lt, int var) { listNode *query = NULL; if(lt == NULL || listNodeLen(lt) <= 0){ return NULL; } listNode *pHead = listNodeHead(lt); listNode *pTail = listNodeTail(lt); if(pHead->var > var || pTail->var < var) { return NULL; } listNode *pCur = pHead; while(pCur != NULL) { if(pCur->var == var) { query = pCur; break; } pCur = listNodeNext(pCur); } return query; } void listNodePrt(list *lt) { if(lt != NULL) { listNode *pCur = listNodeHead(lt); while(pCur != NULL) { listNode *pPrev = listNodePrev(pCur); listNode *pNext = listNodeNext(pCur); printf("listNode =%p,var=%d,prev=%p,next=%p ",pCur,pCur->var,pPrev,pNext); pCur=pNext; } } } int listNodeRelease(list *lt) { int count=0; if(lt == NULL || listNodeLen(lt) == 0) { return count; } listNode *pCur = listNodeHead(lt); while(pCur != NULL) { count++; listNode *pNext = listNodeNext(pCur); free(pCur); pCur = pNext; } return count; } void test(int count, double base) { list *lt=listCreate(); srand((unsigned int) time(NULL)); int i; printf("*************************listNodeAdd******************* "); int ok = 0; int fail = 0; for(i = 0; i < count; i++) { int v =i+ (int)( base *rand()/(RAND_MAX + 1.0)); listNode *tmp =(listNode *)malloc(sizeof(*tmp)); tmp->var = v; int exec = listNodeAdd(lt, tmp); if(exec == 0) { ok++; printf("var=%d,listNodeAdd =%d ",v,exec); } else { fail++; printf("var=%d,listNodeAdd =%d ",v,exec); } } printf("*************************listNodeAdd ok =%d | fail =%d******************* ", ok, fail); ok = 0,fail = 0; printf("********head=%p,tail=%p,listNodeLen=%d***** ",listNodeHead(lt),listNodeTail(lt),listNodeLen(lt)); printf("*************************listNodePrt***************** "); listNodePrt(lt); printf("*************************listNodeQuery***************** "); for(i = 0; i < count; i++) { int v =i+ (int)( base *rand()/(RAND_MAX + 1.0)); listNode *tmp = listNodeQuery(lt,v); if(tmp !=NULL) { ok++; printf("listNodeQuery(%d) =%p,var=%d ",v,tmp,tmp->var); } else { fail++; printf("listNodeQuery(%d) =%p ",v,tmp); } } printf(" ------------>listNodeQuery ok=%d | fail =%d<------------------- ", ok, fail); ok = 0,fail = 0; printf("*************************listNodeDel***************** "); for(i = 0;i < count; i++){ int v =i+ (int)( base *rand()/(RAND_MAX + 1.0)); int exec = listNodeDel(lt,v); if(exec == 0){ ok++; printf("listNodeDel(%d) =%d ",v,exec); }else { fail++; printf("listNodeDel(%d) =%d ",v,exec); } } printf(" --------------->listNodeDel ok =%d | fail =%d<------------------ ", ok, fail); printf("*************************listNodeRelease*************** "); printf("list len = %d,istNodeRelease(%p) =%d ",listNodeLen(lt),lt,listNodeRelease(lt)); } int main(void) { test(30,100.0); return 0; }
运行结果如下:
zhoulin@:~/code_20160101/cas:./ds *************************listNodeAdd******************* var=64,listNodeAdd =0 var=52,listNodeAdd =0 var=67,listNodeAdd =0 var=13,listNodeAdd =0 var=41,listNodeAdd =0 var=15,listNodeAdd =0 var=70,listNodeAdd =0 var=15,listNodeAdd =-1 var=43,listNodeAdd =0 var=17,listNodeAdd =0 var=89,listNodeAdd =0 var=52,listNodeAdd =-1 var=99,listNodeAdd =0 var=74,listNodeAdd =0 var=14,listNodeAdd =0 var=82,listNodeAdd =0 var=97,listNodeAdd =0 var=48,listNodeAdd =0 var=49,listNodeAdd =0 var=69,listNodeAdd =0 var=45,listNodeAdd =0 var=73,listNodeAdd =0 var=106,listNodeAdd =0 var=40,listNodeAdd =0 var=30,listNodeAdd =0 var=122,listNodeAdd =0 var=47,listNodeAdd =0 var=64,listNodeAdd =-1 var=62,listNodeAdd =0 var=127,listNodeAdd =0 *************************listNodeAdd ok =27 | fail =3******************* ********head=0x1a62090,tail=0x1a623d0,listNodeLen=27***** *************************listNodePrt***************** listNode =0x1a62090,var=13,prev=(nil),next=0x1a621f0 listNode =0x1a621f0,var=14,prev=0x1a62090,next=0x1a620d0 listNode =0x1a620d0,var=15,prev=0x1a621f0,next=0x1a62150 listNode =0x1a62150,var=17,prev=0x1a620d0,next=0x1a62330 listNode =0x1a62330,var=30,prev=0x1a62150,next=0x1a62310 listNode =0x1a62310,var=40,prev=0x1a62330,next=0x1a620b0 listNode =0x1a620b0,var=41,prev=0x1a62310,next=0x1a62130 listNode =0x1a62130,var=43,prev=0x1a620b0,next=0x1a622b0 listNode =0x1a622b0,var=45,prev=0x1a62130,next=0x1a62370 listNode =0x1a62370,var=47,prev=0x1a622b0,next=0x1a62250 listNode =0x1a62250,var=48,prev=0x1a62370,next=0x1a62270 listNode =0x1a62270,var=49,prev=0x1a62250,next=0x1a62050 listNode =0x1a62050,var=52,prev=0x1a62270,next=0x1a623b0 listNode =0x1a623b0,var=62,prev=0x1a62050,next=0x1a62030 listNode =0x1a62030,var=64,prev=0x1a623b0,next=0x1a62070 listNode =0x1a62070,var=67,prev=0x1a62030,next=0x1a62290 listNode =0x1a62290,var=69,prev=0x1a62070,next=0x1a620f0 listNode =0x1a620f0,var=70,prev=0x1a62290,next=0x1a622d0 listNode =0x1a622d0,var=73,prev=0x1a620f0,next=0x1a621d0 listNode =0x1a621d0,var=74,prev=0x1a622d0,next=0x1a62210 listNode =0x1a62210,var=82,prev=0x1a621d0,next=0x1a62170 listNode =0x1a62170,var=89,prev=0x1a62210,next=0x1a62230 listNode =0x1a62230,var=97,prev=0x1a62170,next=0x1a621b0 listNode =0x1a621b0,var=99,prev=0x1a62230,next=0x1a622f0 listNode =0x1a622f0,var=106,prev=0x1a621b0,next=0x1a62350 listNode =0x1a62350,var=122,prev=0x1a622f0,next=0x1a623d0 listNode =0x1a623d0,var=127,prev=0x1a62350,next=(nil) *************************listNodeQuery***************** listNodeQuery(30) =0x1a62330,var=30 listNodeQuery(100) =(nil) listNodeQuery(52) =0x1a62050,var=52 listNodeQuery(99) =0x1a621b0,var=99 listNodeQuery(14) =0x1a621f0,var=14 listNodeQuery(93) =(nil) listNodeQuery(12) =(nil) listNodeQuery(81) =(nil) listNodeQuery(105) =(nil) listNodeQuery(51) =(nil) listNodeQuery(92) =(nil) listNodeQuery(87) =(nil) listNodeQuery(96) =(nil) listNodeQuery(83) =(nil) listNodeQuery(52) =0x1a62050,var=52 listNodeQuery(99) =0x1a621b0,var=99 listNodeQuery(54) =(nil) listNodeQuery(36) =(nil) listNodeQuery(33) =(nil) listNodeQuery(89) =0x1a62170,var=89 listNodeQuery(89) =0x1a62170,var=89 listNodeQuery(61) =(nil) listNodeQuery(44) =(nil) listNodeQuery(76) =(nil) listNodeQuery(81) =(nil) listNodeQuery(53) =(nil) listNodeQuery(76) =(nil) listNodeQuery(106) =0x1a622f0,var=106 listNodeQuery(93) =(nil) listNodeQuery(114) =(nil) ------------>listNodeQuery ok=9 | fail =21<------------------- *************************listNodeDel***************** listNodeDel(78) =-1 listNodeDel(97) =0 listNodeDel(86) =-1 listNodeDel(32) =-1 listNodeDel(97) =-1 listNodeDel(100) =-1 listNodeDel(23) =-1 listNodeDel(106) =0 listNodeDel(77) =-1 listNodeDel(23) =-1 listNodeDel(52) =0 listNodeDel(63) =-1 listNodeDel(103) =-1 listNodeDel(39) =-1 listNodeDel(36) =-1 listNodeDel(44) =-1 listNodeDel(27) =-1 listNodeDel(77) =-1 listNodeDel(66) =-1 listNodeDel(45) =0 listNodeDel(51) =-1 listNodeDel(39) =-1 listNodeDel(89) =0 listNodeDel(76) =-1 listNodeDel(95) =-1 listNodeDel(50) =-1 listNodeDel(108) =-1 listNodeDel(49) =0 listNodeDel(33) =-1 listNodeDel(77) =-1 --------------->listNodeDel ok =6 | fail =24<------------------ *************************listNodeRelease*************** list len = 21,istNodeRelease(0x1a62010) =21
zhoulin@:~/code_20160101/cas:gcc -g ds.h ds_pt.c -O2 -o ds //使用gcc原子操作函数 zhoulin@:~/code_20160101/cas:gcc -g ds1.h ds_pt1.c -O2 -o ds1 -lpthread //使用pthread_mutex_t进行原子操作 zhoulin@:~/code_20160101/cas:time ./ds *************************listNodeRelease*************** list len = 8008,listNodeRelease(0x1d51010) =8008 real 0m5.809s user 0m5.770s sys 0m0.004s zhoulin@:~/code_20160101/cas:time ./ds1 *************************listNodeRelease*************** list len = 8051,listNodeRelease(0x21cd010) =8051 real 0m6.231s user 0m6.220s sys 0m0.002s