快速排序 (QuickSorting) 是对冒泡排序的一种改进,由 C.A.R.Hoare 在 1962 年提出。
它的基本思想是:
通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部数据分别进行快速排序,
整个排序过程可以递归进行,以此达到整个数据变成有序序列。
1、先从数列中取出一个数作为基准数
2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
3、再对左右区间重复第二步,直到各区间只有一个数
接下来我们举例说明:
第一步,l=0,r=9,pivot=21
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
21 | 32 | 43 | 98 | 54 | 45 | 23 | 4 | 66 | 86 |
第二步,从r开始由,后向前找,找到比pivot小的第一个数a[7]=4,此时l=0,r=6,pivot=21
进行替换
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
4 | 32 | 43 | 98 | 54 | 45 | 23 | 21 | 66 | 86 |
第三步,由前往后找,找到比pivpt大的第一个数a[1]=32,此时l=2,r=6,pivot=21
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
4 | 21 | 43 | 98 | 54 | 45 | 23 | 32 | 66 | 86 |
第四步,从r=6开始由,由后向前找,找到比pivot小的第一个数a[0]=4,此时l=2,r=0,pivot=21,发现j<=i,所以第一回结束.。
可以发现21前面的数字都比21小,后面的数字都比21大
接下来对两个子区间[0,0]和[2,9]重复上面的操作即可。
下面是代码实现部分:
class QuickSort{
public void sort(int left, int right, int arr[])
{
int l = left; //获取传进来数组的左边边界
int r = right; //获取传进来数组的右边边界
int pivot = arr[(left+right)/2]; //设置我们要比较的数,这里取的是数组中间元素的值
int temp = 0;
/**
* 注意:这里的比较方式是左右交替进行
*/
while(l<r)
{
//从右边开始,逐一向左变比较,直到找到比pivot小或者等于的值
while(arr[r] > pivot)
r--;
//从左边开始,逐一向右变比较,直到找到比pivot大或者等于的值
while(arr[l] < pivot)
l++;
//当while左右都结束后,仍然没有找到这个值,
//这个时候l至少会等于或者大于r
if(l >= r)
break;
//当找到这个值的时候,对调arr[l], arr[r]元素的位置
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
if(arr[l] == pivot) --r;//当l和比较的元素相等时,r左移一位
if(arr[r] == pivot) ++l;//当r和比较的元素相等时,l右移一位
}
//当l和r相当时,l右移一位,r左移一位
//方便后面,切成两份后,l是新分区的左边,r是新分区的右边
if(l == r)
{
l++;
r--;
}
//对新分区继续进行比较,直到不能再分区为止。
//这个时候顺序就排好了
if(left < r)
sort(left, r, arr);
if(right > l)
sort(l, right, arr);
}
}
然后是调用部分:
int arr[] = {21, 32, 43, 98, 54, 45, 23, 4, 66, 86};
QuickSort qs = new QuickSort();
qs.sort(0, arr.length-1, arr);
for(int i = 0; i < arr.length; i++)
{
System.out.println("arr[" + i + "] = " + arr[i]);
}
最后的运行结果是如下: