最近要交高级语言程序设计作业,由于不满足于插入排序的低效率,便顺手撸了一个基于单链表的快排。
虽然网络上已经有很多这样的博客了,不过还是贴上来吧,毕竟自己敲的模板用起来最顺手是吧= =。
嘛,这个函数默认不带头结点,返回值为结点首地址。
所以对于带头节点来说就要酱:
head->next=QUICK_SORT( head->next , &head );
不过大家那么聪明肯定不用提醒了 ╮( ̄▽ ̄”)╭
进入正文
#define NODE 要排序的结构体名字
#define ATTR 这里填要排序的属性
#define NEXT 这里填存储下一个结点的变量名
/**
参数一为待排序的链表头结点
参数二返回的为排序以后的尾节点地址
*/
NODE* QUICK_SORT (NODE* SOUR,NODE **REAR)
{
if(SOUR==NULL) //为空结点
{
//此情况只有一种可能:要排序的链表是一个空链表
return NULL;
}
NODE *MID=SOUR,*L=NULL,*R=NULL; //中点、左侧、右侧
NODE *RR,*LR; //左侧尾结点,右侧尾结点
NODE *TEMP,*P=SOUR->NEXT; //定位主串剩余串
while(P) //循环拆解原串
{
TEMP=P->NEXT;
if(P->ATTR < MID->ATTR) //这里填排序规则(如字符串排序 strcmp(P->ATTR , MID->ATTR)<0)
{
if(L==NULL) //L为空串
{
L=LR=P;
L->NEXT=NULL;
}else
{
P->NEXT=L;
L=P;
}
}else //说明排在MID后
{
if(R==NULL)
{
R=RR=P;
R->NEXT=NULL;
}else
{
P->NEXT=R;
R=P;
}
}
P=TEMP;
}
//拆解完毕,进行递归拆解
if(L!=NULL&&R!=NULL)
{
L=QUICK_SORT(L,&LR);
R=QUICK_SORT(R,&RR);
//合并已有序的链表
LR->NEXT=MID;
MID->NEXT=R;
*REAR=RR; //上传尾结点
return L;
}else if(R!=NULL)
{
R=QUICK_SORT(R,&RR);
MID->NEXT=R;
*REAR=RR;
return MID;
}else if(L!=NULL)
{
L=QUICK_SORT(L,&LR);
LR->NEXT=MID;
*REAR=MID;
return L;
}
//说明只有MID一个元素
*REAR=MID;
return MID;
}