快速排序
1.基本思想:
- 先从数列总选一个数作为基准数
- 把比这个数大的数全放到它的右边,把比这个数小的全放到它的左边
- 再对左右区间重复第二步,直到各区间只有一个数
2.以数组为例:
下标:0 1 2 3 4 5 6 7 8 9
数值:72 6 57 88 60 42 83 73 48 85
初始化:i=0;j=9;X=a[i];(X=72)
i 代表数组左边(初值为最左边),j 代表数组右边(初值为最右边)
第一步:
将a[0]的数值赋值给X,相当于找了一个临时变量,这时a[0]的值可以随意改变,因为由X保存。即a[0]为一个“坑”,按照排序的原则,我们应该把比它小的数(或者等于它的数)放到它左边。
第二步:
从j开始(从右边开始往左边【j--】)找比X(临时值)【从坑里拿出来的值】小或者等于它的数。当j=8,符合条件,这时直接将符合条件的值,填入坑中,即a[0]=a[8]。这个由i值标识的坑已经被填入了符合条件的值,所以i向右移动,即i++;。然后形成了一个新的坑a[8],再找数字来填a[8]这个坑。注意X的值不变!
第三步:
j已经用过了,开始用i,即从左边开始往右边【i++】寻找比X大的值,当i=3,符合条件,将a[3]挖出再填到上一个坑a[8]中。即a[8]=a[3];j--;这个由j值标识的坑已经被填入了符合条件的值,所以j向左移动,即j--;。
第四步:
重复上面两步,直到i和j相遇。
生成新数组:
0 1 2 3 4 5 6 7 8 9
48 6 57 42 60 ? 83 73 88 85
然后发现相遇的地方值不准确。
所以最后把之前最先挖出来用于做比较的临时变量X,填进去。
即a[i]=X;或者a[j]=X;
即数组为:
0 1 2 3 4 5 6 7 8 9
48 6 57 42 60 72 83 73 88 85
这之后a[5]【临时变量】前面的数字都小于它,后面的数字都大于它。但是这些数字不是有序的,因此再对a[0...4]和a[6...9]进行排序即可。
3.成品代码展示:
#include <stdio.h>
#include <stdlib.h>
#define N 16
int partition(int arr[],int left,int right)
{
int key = arr[left];
while(left<right)
{
while(left<right&&arr[right]>=key)right--;
if(left<right)arr[left++] = arr[right];
while(left<right&&arr[left]<=key)left++;
if(left<right)arr[right--] = arr[left];
}
arr[left] = key;
return left;
}
void quick_sort(int arr[],int start,int end)
{
int pos;
if(start<end)
{
pos = partition(arr,start,end);
quick_sort(arr,start,pos-1);
quick_sort(arr,pos+1,end);
}
}
void main()
{
int i;
int arr[N]= {32,12,7,78,23,45,11,22,33,44,55,66,77,88,99,100};
quick_sort(arr,0,N-1);
for(i=0; i<N; i++)printf("%d ",arr[i]);
}
以上内容转载修改自博客: