快速排序(quick sort)是计算机领域一个重要的算法。
初学快排,理解起来并不难,核心理念主要是选取pivot轴心元素(选取pivot元素也有一定技巧,可能会影响到算法的复杂度,需要多加揣摩),再从左向右寻找第一个比pivot元素大的值,从右向左寻找第一个比pivot元素小的值,当两个“记号”都找到符合条件的值,将两者交换位置。当两个负责寻找的“记号”相遇,一轮循环结束。最后将记号相遇所在位置的值与pivot值再交换。这是整个序列被pivot值分成了两个分区。接下来分别调用自身进行递归,对pivot左边的全体序列与pivot右边的全体序列进行相同处理。
整个算法到此结束。基础代码如下:
void quickSort(int a[], int left, int right)
{
int temp = a[left];// pivot
int i = left, j = right;
if (left > right)
return;
while (i < j) // main
{
while (a[j] >= temp && i < j)
j--;
while (a[i] <= temp && i < j)
i++;
int t = a[i]; //swap
a[i] = a[j];
a[j] = t;
}
a[left] = a[i];
a[i] = temp;
quickSort(a, left, i - 1); // left recursion
quickSort(a, i + 1, right); // right recursion
return;
}
但是这样基础的代码并不稳定,需要进一步的优化。
这次的pivot值不在直接选取left,即最左边第一个值,而是使用(left+right)/2 所处位置的值。需要注意的是,改进的算法核心在于while(i <= j)这个循环,记号i, j不在像是原算法每次循环都从最左和最右遍历,而是不断的向前直到两者相背(i > j),然后再进行递归,这样在循环时比原算法节省了时间,更加快速。
void quickSort(int a[], int left, int right)
{
int temp = a[(left+right)/2];// pivot
int i = left, j = right;
if (left > right) // special situation, return
return;
while (i <= j) // main
{
while (a[j] > temp)
j--;
while (a[i] < temp)
i++;
if (i <= j)
{
int t = a[i]; //swap
a[i] = a[j];
a[j] = t;
i++;
j--;
}
}
if(i < right)
quickSort(a, i, right); // left recursion
if(j > left)
quickSort(a, left, j); // right recursion
return;
}