说到快速排序,基于数组时,我们一般使用两个指针,一个指向首元素,一个指向尾元素,通过这两个指针的移动和交换达到快排的目的,但是当基于单链表时,此方法就行不通了,因为单链表是单向的,只有后继指针,无前驱指针,只能向后遍历,不能向前遍历。那么基于单链表时到底应该怎样进行快速排序呢?本文针对于该问题给出具体的解决方法。
思路:定义两个指针pfirst和psecond,前者初始化为传入的头结点begin,后者初始为pfirst->pnext。pfirst始终指向遍历到目前为止的单链表中比基准值小的节点的组成的单链表的尾节点,当pfirst->mdata<base_key时,pfirst后移(pfirst=pfirst->pnext),交换这两个指针所指向的节点的元素值;psecond后移。即这两个指针均向右端移动,移动的过程中保持pfirst之前的key都小于选定的base_key,pfirst与psecond之间的key都大于选定的base_key,那么当psecond走到末尾时便完成了一趟快排。
以单链表元素{8,2,5,3,10,7}为例,进行一趟快排的详细过程如下:
代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
typedef struct Node
{
int mdata;
struct Node* pnext;
}Node,*PNode;
void Init(PNode* phead)
{
if (phead == NULL)
{
return;
}
*phead = NULL;
}
PNode BuyNode(ELEM_TYPE val)
{
PNode pnewnode = (PNode)malloc(sizeof(Node));
if (pnewnode == NULL)exit(0);
pnewnode->mdata = val;
pnewnode->pnext = NULL;
return pnewnode;
}
bool InsertTail(Node** phead, ELEM_TYPE val)
{
if (phead == NULL)
{
return false;
}
if (*phead == NULL)
{
PNode pnewnode = BuyNode(val);
*phead = pnewnode;
return true;
}
PNode pCur = *phead;
while (pCur->pnext != NULL)
{
pCur = pCur->pnext;
}
PNode pnewnode = BuyNode(val);
pCur->pnext = pnewnode;
return true;
}
void Show(PNode phead)
{
PNode pCur = phead;
while (pCur != NULL)
{
printf("%d ", pCur->mdata);
pCur = pCur->pnext;
}
printf("\n");
}
void quick_sort(PNode begin,PNode end)
{
if (begin==NULL || end==NULL || begin==end) return;
PNode pfirst=begin;
PNode psecond=pfirst->pnext;
int base_key=begin->mdata;
while(psecond!=NULL)
{
if(psecond->mdata<base_key)
{
pfirst=pfirst->pnext;
std::swap(pfirst->mdata,psecond->mdata);
}
psecond=psecond->pnext;
}
std::swap(begin->mdata,pfirst->mdata);
quick_sort(begin,pfirst);
quick_sort(pfirst->pnext,end);
}
int main()
{
PNode phead1;
Init(&phead1);
InsertTail(&phead1,8);
InsertTail(&phead1,2);
InsertTail(&phead1,5);
InsertTail(&phead1,3);
InsertTail(&phead1,10);
InsertTail(&phead1,7);
Show(phead1);
PNode pb=phead1;
PNode pe=phead1;
while(pe->pnext!=NULL)
{
pe=pe->pnext;
}
quick_sort(pb,pe);
Show(phead1);
return 0;
}
运行结果如图: