快速排序是对起泡排序的一种改进。它的基本思想是,通过一趟排序将代排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
假设待排序的序列为{L.r[ s ], L.r[ s + 1],···.L.r[ t ]},首先任意选取一个记录(通常可选第一个记录L.r[s])作为枢轴,然后按下述原则重新排列其余记录。将所有关键字较它小的记录都安置在他的位置之前,将所有关键字较它大的记录都安置在他的位置之后。由此可以该“枢轴”记录最后所落的位置i作分界线,将序列{L.r[s],···,L.r[t]}分割成两个子序列{L.r[s],L.r[s+1],···,L.r[i -1]}和{L.r[i+i],L.r[i + 2],···,L.r[t]}。这个过程称做一趟快速排序。
一趟快速排序的具体做法是:附设两个指针low和high,他们的初值分别为low和high,射枢轴记录的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和枢轴记录互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交换,重复这两步直至low = high为止。
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}