排序思路:
分而治之。以首位元素作为分割标准(pivot),小于该值的元素(无需排序)置于pivot前部,大于该值的元素(无需排序)置于pivot后部。采用递归思想,对“前部数组”进行分割,后部数组同样进行分割。直到无法继续“分割”。
样例:
{22,35,16,9,5,20}
1.设定游标j指向数组末尾;设定游标i指向数组起始位。
2.找标志位(一般的,我们取array[i]作为我们的首位)
{__,35,16,9,5,20} pivot=22 (i=0, j=5)
3.若array[j]小于key,则将array[j]赋值给array[i]
{20,35,16,9,5,__} pivot=22 (i=0, j=5)
4.若array[i]大于key,则将array[i]赋值给array[j]
{20,__,16,9,5,35} pivot=22(i=1, j=5)
5.从之前游标j停止的位置,继续重复步骤3
{20,5,16,9,__,35} pivot=22(i=1, j=4)
6.从之前游标i停止的位置,继续重复步骤4
此时,我们发现,当i=4时,已经与j发生重合,数组已经遍历了一遍。“分割”操作结束。我们将key值填入array[4]。
{20,5,16,9,22,35} pivot=22(i=4, j=4)
7.至此,我们选取原始array[0]值作为pivot,已经将数组分割成{20,5,16,9} {22} {35}。我们再对{20,5,16,9}进行划分。重复步骤1,如此往复。
{__,5,16,9} pivot=20 (i=0, j=3)
{9,5,16,__} pivot=20 (i=0, j=3)
{9,5,16,20} pivot=20 (i=3, j=3)
中间结果:{9,5,16} {20} {22} {35}
{__,5,16} pivot=9 (i=0, j=2)
{5,__,16} pivot=9 (i=0, j=1)
{5,9,16} pivot=9 (i=1, j=1)
中间结果:{5,9}{16} {20} {22} {35}
{__,9} pivot=5 (i=0,j=1)
{5,9} pivot=5 (i=1,j=1)
中间结果:{5}{9}{16} {20} {22} {35}
最终结果:
{5,9,16,20,22,35}
c实现
void quickSort(int array[], int start, int end) {
if(start>=end){
return;
}
int i=start;
int j=end;
int pivot=array[i];
while(i<j){
while(array[j]>pivot && i<j){
j--;
}
array[i]=array[j];
while(array[i]<pivot && i<j){
i++;
}
array[j]=array[i];
}
array[i]=pivot;
quickSort(array, start, i-1);
quickSort(array, i+1, end);
}
平均时间复杂度为O(nlogn),最坏为O(n2)。