您的位置:首页 > 运维架构 > Linux

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

2016-01-02 19:37 489 查看
实现插入自动排序的双向链表,插入的的每个元素是唯一且是排序好的,从链表头到链表尾部都是按照从小到大的顺序的


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: