鏈表排序(冒泡、歸併)

排序的算法很多,這裏說明連接件的冒泡排序和歸併排序的實現,以升序爲例。
冒泡排序的原理:每一趟比較相鄰兩個連接件的數據部件,如果大值部件在前驅,則交換兩個連接件的位置,使之成爲後繼,直至所有數據部件的值都按照升序排列。
歸併排序的原理:遞歸劃分連接件鏈表,直至最小劃分,然後升序合併劃分的連接件鏈表,直至所有的劃分都被合併。
數據部件的比較通過調用回調函數的返回值來判斷,回調函數有具體應用實現。
 

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章