快速排序算法的主要思想是分段与递归。
分段:取出一个元素,将它放到一个特定位置,是的左边的数全小,右边的数全大
递归:对左边的数执行该算法,对右边的数执行该算法。
那么,分段过程中,如何找到这样一个特定的分段位置呢?来看一下算法在递归前的运行过程。
假设有一个数组,其中7个数如下图所示,需要进行快排。
我们需要i,j 做两个下标,指向数组两头,还有一个临时变量temp,用来当临时的容器。
首先,取出第一个数放到数组外面,存到temp变量里最后用,于是5的位置相当于腾空了(蓝色标识)。
第二步:j方向依次找比5小的数,很巧,3就是,于是3放到原先5的位置,i下标+1;
第三步:从i方向开始找比5大的数,4,1,2都比5小,于是i连续移动到了6的位置,将6放入原先3的位置(黄色标识),j下标-1。
第四步:从j方向找比5小的数,j–,直到与i重合,也没再发现比5小的数,此时ij都在6上
最后,把最开始放在临时容器的5放到此时ij重合的位置,这个位置就是之前说的分解位置,再用一个变量k记住这个位置。
剩下的事就是递归了,左边做一次,右边再做一次,算法完成。
快速排序的代码不算太长,C语言版本的算法代码如下:
void QuickSort(int *array,low,high)
{
if(low>=high)return;
int i,j; //记录数组高低边界
int temp; //存储临时取出的数
int k; //记录分解数组下标
i=low;
j=high;
temp=array[i]; //先存下数组第一个数
while(i<j)
{
while(array[j]>temp && i<j)
{
j--; //连续移动j下标,直到找到右边比temp小的数
}
if(i<j)
{
array[i]=array[j];
i++;
}
while(array[i]<temp && i<j)
{
i++; //连续移动数组i下标,直到直到左侧比temp大的数
}
if(i<j)
{
array[j]=array[i];
j--;
}
}
//出了这个while循环,表明i=j
array[i]=temp;
k=i;
QuickSort(array,low,k-1);
QuickSort(array,k+1,high);
}