排序的演算法很多,這裡說明串連件的冒泡排序和歸併排序的實現,以升序為例。冒泡排序的原理:每一趟比較相鄰兩個串連件的資料組件,如果大值組件在前驅,則交換兩個串連件的位置,使之成為後繼,直至所有資料組件的值都按照升序排列。歸併排序的原理:遞迴劃分串連件鏈表,直至最小劃分,然後升序合并劃分的串連件鏈表,直至所有的劃分都被合并。資料組件的比較通過調用回呼函數的傳回值來判斷,回呼函數有具體應用實現。
typedef int (*LinkSortCall)(LINKPTR plk1,LINKPTR plk2,void* param);
/**//*
功能:定義串連件的排序的回呼函數
參數:plk1,plk2為資料連線件指標,param為回傳參數
返回:0為(plk1)=(plk2),1為(plk1)>(plk2),-1為(plk1)<(plk2)
*/
XDL_API void BubbleSortLink(LINKPTR root,LinkSortCall pf,void* parm);
/**//*
功能:對鏈表進行冒泡排序
參數:root為根串連件指標,pf為排序回呼函數,param為回調參數
返回:無
*/
XDL_API void MergeSortLink(LINKPTR root,LinkSortCall pf,void* parm);
/**//*
功能:對鏈表進行歸併排序
參數:root為根串連件指標,pf為排序回呼函數,param為回調參數
返回:無
*/
void BubbleSortLink(LINKPTR root,LinkSortCall pf,void* parm)
...{
LINKPTR prev,next;
int tag = 1;
assert(root && root->tag == lkRoot);
assert(pf);
while(tag)
...{
tag = 0;
prev = GetFirstLink(root);
while(prev)
...{
next = GetNextLink(prev);
if(next == NULL)
break;
if((*pf)(prev,next,parm) > 0)
...{
SwitchLinkToNext(prev);
tag = 1;
}else
prev = next;
}
}
}
//劃分串連件
int _DivLink(LINKPTR root1,LINKPTR root2)
...{
int count,tag;
tag = LinkCount(root1);
count = tag / 2;
while(count--)
...{
InsertLink(root2,LINK_FIRST,DeleteLink(root1,LINK_LAST));
}
return tag;
}
//合并串連件
void _MrgLink(LINKPTR root1,LINKPTR root2,LinkSortCall pf,void* parm)
...{
LINKPTR next1,next2;
LINKPTR plk;
next1 = GetFirstLink(root1);
next2 = GetFirstLink(root2);
while(next1 != NULL && next2 != NULL)
...{
if((*pf)(next1,next2,parm) > 0)
...{
plk = GetNextLink(next2);
InsertLinkBefore(root1,next1,DeleteLink(root2,next2));
next2 = plk;
}else
...{
next1 = GetNextLink(next1);
}
}
while(next2 != NULL)
...{
plk = GetNextLink(next2);
InsertLink(root1,LINK_LAST,DeleteLink(root2,next2));
next2 = plk;
}
}
void MergeSortLink(LINKPTR root,LinkSortCall pf,void* parm)
...{
LINK lk;
InitRootLink(&lk);
if(_DivLink(root,&lk) > 1)
...{
MergeSortLink(root,pf,parm);
MergeSortLink(&lk,pf,parm);
_MrgLink(root,&lk,pf,parm);
}
}
collected by barenx