快速排序又称为划分交换排序。其基本思想是:在待排序数列中任选出一个数作为基准,用这个基准将数列划分为左右两个子区,使得左子区的数都不大于基准数,而右子区的数都不小于基准数,称为完成第一次划分。如果左子区或右子区不为空,则对它进行同样的划分,直至为空为止。
要实现第一次划分,具体的做法是,设置两个指针,一个从右往左扫描,发现比基准数小的就和基准数交换;同时另一个从左往右扫描,发现比基准数大的就和基准数交换,那么,当两个指针相遇的时候,左边的数已经都比基准数小,右边的都比基准数大,而指针指的地方刚好就是基准数的最终位置。
public static void QUICKSORT(int[] N,int left,int right)
{
//数组元素如果不大于一个就无需排序。
if (left < right)
{
int p = PARTITION(N, left, right); //第一次划分
QUICKSORT(N, left, p-1); //递归处理左子区
QUICKSORT(N, p+1, right); //递归处理右子区
}
}
//划分
public static int PARTITION(int[] R, int left,int right)
{
int i = left;
int j = right;
int temp = R[i];
while (i != j)
{
//从左往右扫描,查找第一个比基准数小的数
while ((R[j] >= temp) && (i<j))
{
j--;
}
if (i < j)
{
//交换找到的数和基准数,由于基准数还需交换多次,所以暂时不用将temp->R[j]
R[i] = R[j];
i++;
}
while ((R[i] <= temp) && (i < j))
{
i++;
}
if (i< j)
{
R[j] = R[i];
j--;
}
}
//定位基准数
R[i] = temp;
return i;
}
顺便提一下,上面的递归算法用到的方法叫做“分治法”(divide_and_comquer),就是使用两个递归调用,每个调用处理将整个问题划分成两个独立的子问题来解决。