Linux实现插入排序的双向链表

 

    实现插入自动排序的双向链表,插入的的每个元素是唯一且是排序好的,从链表头到链表尾部都是按照从小到大的顺序的    

 

 

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\n",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*******************\n");
    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\n",v,exec);
        } else {
            fail++;
            printf("var=%d,listNodeAdd =%d\n",v,exec);
        }
    }
    printf("*************************listNodeAdd ok =%d | fail =%d*******************\n\n", ok, fail);
    ok = 0,fail = 0;
    printf("********head=%p,tail=%p,listNodeLen=%d*****\n\n",listNodeHead(lt),listNodeTail(lt),listNodeLen(lt));
    printf("*************************listNodePrt*****************\n");
    listNodePrt(lt);
    printf("*************************listNodeQuery*****************\n");
    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\n",v,tmp,tmp->var);
        } else {
            fail++;
            printf("listNodeQuery(%d) =%p\n",v,tmp);
        }
    }
    printf("   ------------>listNodeQuery ok=%d | fail =%d<-------------------\n\n", ok, fail);
    ok = 0,fail = 0;
    printf("*************************listNodeDel*****************\n");
    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\n",v,exec);
        }else {
            fail++;
            printf("listNodeDel(%d) =%d\n",v,exec);
        }
    }
    printf("   --------------->listNodeDel ok =%d | fail =%d<------------------\n\n", ok, fail);
    printf("*************************listNodeRelease***************\n");
    printf("list len = %d,istNodeRelease(%p) =%d\n",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

 

posted @ 2016-01-02 19:37  一个万能盒子叫数据库  阅读(861)  评论(0编辑  收藏  举报