说来快速排序是属于交换排序的一种。
其思想(对于升序排序来说):
1. 首先是分割操作:任意选择数组中的任意元素作为中位数,此中位数将数组分为两部分A[.....,中位数,.....]
2. 左半部分的数值都小于或等于此中位数,右半部分的数值都大于或等于此中位数。
3. 然后对左半部分的数组进行递归分割操作,对右半部分的数组进行递归分割操作。直到每一个部分只有一个元素或为空为止,则所有元素放在了它应该在的位置上。
注意!
每一次分割操作,都产生一个中位数,而每次分割后,这个中位数就在它最终排序的位置上。
分割操作:如下例子:
下标:0 1 2 3 4 5 6 7
数值:49 38 65 97 76 13 27 49
1. 选取数组中的任意一个元素作为中位数。这里我们选取A[0]==49.且int temp=A[0];将中位数的值记录下来。
2. 设置两个标记值low和high来记录当前的下标,low的初始值为0,high的初始值为7.
3. 从high==7开始看起,A[high]==49,A[high]>=temp,则high=high-1;则此时看high==6;A[high]==27, A[high]<temp,则让A[low]=A[high]
下标:0 1 2 3 4 5 6 7
数值:27 38 65 97 76 13 27 49
4. 从low==0开始看起,A[low]<=temp,则low=low+1;
此时low==1;再看A[low]==38, A[low]<=temp;则low=low+1;
此时low==2;再看A[low]==65,A[low]>temp;则A[high]=A[low];
下标:0 1 2 3 4 5 6 7
数值:27 38 65 97 76 13 65 49
5. high==6;A[high]>=temp;high-=1;
high==5;A[high]<temp;A[low]=high;
下标:0 1 2 3 4 5 6 7
数值:27 38 13 97 76 13 65 49
6. low==2; A[low]<=temp;low+=1;
low==3; A[low]>temp;A[high]=A[low];
下标:0 1 2 3 4 5 6 7
数值:27 38 13 97 76 97 65 49
7. high==5; A[high]>=temp;high-=1;
high==4; A[high]>=temp;high-=1;
high==3;
!!!!注意此时low==3;high==low;则此次分割结束。且A[high/low]=temp;
下标:0 1 2 3 4 5 6 7
数值:27 38 13 49 76 97 65 49
分割结束!此次的中位数为49.且它落于下标为3的位置上。
int Partion(int A[],int low,int high){
int temp=A[low];
while(low<high){
while(low<high&&temp<=A[high])
high--;
A[low]=A[high];
while(low<high&&temp>=A[low])
low++;
A[high]=A[low];
}
A[high]=temp;
return high;
}
void QuickSort(int A[],int low,int high){
if(low<high){
int p=Partion(A,low,high);
QuickSort(A,low,p-1);
QuickSort(A,p+1,high);
}
}
注意! while(low<high&&temp<=A[high])和while(low<high&&temp>=A[low])如果改为
while(low<high&&temp<A[high])和while(low<high&&temp>A[low])行不行?
答案是否定的!不行!
如果在分割过程中,数组中有一个数与中位数相等,则会出现死循环。
按照上面的例子来看,如果改为下面的条件的话,在分割操作的步骤1中,此时high==7,low==0,
进入循环while(low<high&&temp<A[high])high--;49==49,则直接跳出while循环,A[7]=49;high还是等于7;
然后,进入第二个while循环while(low<high&&temp>A[low])low--;再看此时A[low]==49;temp==49;则也直接跳出循环,A[7]==49;low还是等于0;
这样就会进入死循环,它一直呆在这里不动,low和high始终是0和7。
注意!
循环条件while(low<high)不是while(low<=high).当low==high时,就表示应该终止了,中位数的位置已经找到了。