基于快排思想如下:
我们设置两个指针p,q,其中 p初始时指向数组的第一个元素,q初始化为 p->next。
然后,我们设定 p 指向的元素为基准数字。
我们要做的事情,就是在一趟排序中,把那些比基准数字小的数,移动到前面。
具体的算法如下:
如果q指向的值大于等于基准数字(如果比基准大,直接跳过)
q = q -> next
如果q指向的值小于基准数字,(如果比基准小,交换p 和 q位置的值)
p = p -> next
swap(p, q)
q = q->next
核心代码如下,如有错误,欢迎指正:
void swap(Link phead,Link p , Link q)
{
int t = p->mdata;
p->mdata = q->mdata;
q->mdata = t;
}
void Quicksort(Link phead,int left,int right)
{
if(left < right)
{
Link p = phead->pnext; // 初始化p,为链表第一个元素(最左边的元素)
left++;
Link q = p->pnext; // 初始化q
Link x = phead->pnext; // 基准数字
while(q->pnext != NULL) { // 大循环条件,q不能超过链表长度
// 如果q指向的值大于等于基准数字(如果比基准大,直接跳过)
while(q->pnext != NULL && q->mdata >= x->mdata) q=q->pnext;
// 否则,q指向的值小于基准,则交换
if(q->pnext != NULL) {
p = p->pnext; // 交换时,p 首先要向后移动一位
left++;
swap(phead, p, q); // 交换
q=q->pnext; // 随后,q向后移动一位
}
}
swap(phead, x, p); // 最后,交换 p 位置的值和基准元素。一趟排序结束。
Quicksort(phead, 0, left-1); // 递归排序左边
Quicksort(phead, left+1, right); // 递归排序右边
}
}
在交换的时候,为什么要让p先向后移动呢?
这是因为,在整个排序的过程中,p前面指向的都是小于基准的数字,p后面指向的都是大于基准的数字,p是左右两边的分界线。我们交换的目的是把小于基准的交换到前面,把大于基准的交换到后面,所以p要先向后移动1位,找到后面第一个大于基准的数,然后把这个大于基准的数,和后面小于基准的数交换。