一、快速排序算法是对冒泡算法的改进,算法的思想是:
1.每一趟排序选定一个基元素,这一趟排序完成后,比基元素小的元素在基元素的左边,比基元素大的元素在基元素的右边。
2.对基元素左边和右边的元素进行如1的排序
…..循环1、2
直到左边的元素大于右边元素,排序完成。
二、快速排序的时间复杂度:O(nlogn)
三、快速排序的空间复杂度:
快排使用的空间是O(1),但是真正消耗空间的是递归,因为递归调用要保存临时数据。
最优的空间复杂度:O(logn),每一都平均分组情况。
最差的空间复杂度:O(n),退化为冒泡算法。
四、手工过程
3 7 4 2 5 1 8
第一趟排序:把下标为0的3作为基元素
r:记录从右边比较的下标。
l:记录从左边比较的下标。
起始:r = n.length - 1 = 6, l = 0
从右边开始比较,右边元素大于基元素不交换,下标向左移,右边元素小于左边元素,交换,改变方向:
3 < 8:不交换 r– 3 7 4 2 5 1 8
l r–
3 > 1:交换3和1 r=5 1 7 4 2 5 3 8
l r
一旦交换,就改变方向,此时的基元素的下标就是r,从左边开始与基元素3开始比较,左边元素小于基元素,l++,反之,交换,改变比较的方向 :
1 < 3 :不交换,l++ 1 7 4 2 5 3 8
l++ r
7 > 3 :交换, 1 3 4 2 5 7 8
l r
交换后改变方向,此时基元素3的下标为l = 1
从右边的r开始依次与基元素进行比较:
3 < 7 :不交换,r– 1 3 4 2 5 7 8
l r–
3 < 5 :不交换,r– 1 3 4 2 5 7 8
l r–
3 > 2 :交换 1 2 4 3 5 7 8
l r
交换后改变方向,此时基元素3的下标为r = 3
从左边的r开始依次与基元素进行比较:
3 > 2 :不交换,l++ 1 2 4 3 5 7 8
l++ r
3 < 4 :交换 1 2 3 4 5 7 8
l r
交换后改变方向,此时基元素3的下标为l = 2
3 < 4 :不交换,r– 1 2 3 4 5 7 8
l r–
比较到这r == l时,一趟排序才比较完成了, 此时小于3的元素都在3的坐标,大于3的元素都在3的右边。
然后对3左边和右边的元素进行如上所述的排序….
五、代码
package com.zhangyike.quickSort;
import java.util.Arrays;
import java.util.Random;
public class QuickSort{
public static void quickSort(int[] arr, int left, int right){
//检验数组
if (arr == null || arr.length < 1) {
throw new RuntimeException("数组不能为空!");
}
//检验下标
if (left < 0 || left > arr.length || right < 0 || right > arr.length) {
throw new IndexOutOfBoundsException("数组下标不合法!");
}
//循环停止的条件
if (left > right) {
return;
}
int l = left;
int r = right;
int key = arr[l];
boolean derict = true;
while(l < r){
//key从后开始比
if (l < r && derict) {
//key小于等于最后r,r向前移动
while (l < r && key <= arr[r]) {
r--;
}
//key大于最后r,交换两个元素,此时下标为r的就是可以值,并且改变方向
if (l < r && key > arr[r]) {
swap(arr,l,r);
derict = false;
}
}
//key从前开始比
if (l < r && !derict) {
//key大于等于l,l向后移动
while (l < r && key >= arr[l]) {
l++;
}
//key小于l,交换,并且改变方向
if (l < r && key < arr[l]) {
swap(arr,l,r);
derict = true;
}
}
}
//对key前面的元素排序
if (l > left) {
quickSort(arr,left,r-1);
}
//对key后面的元素排序
if (right > r) {
quickSort(arr,l+1,right);
}
}
private static void swap(int[] arr, int l, int r) {
arr[r] = arr[r] ^ arr[l];
arr[l] = arr[r] ^ arr[l];
arr[r] = arr[r] ^ arr[l];
}
public static void main(String[] args) {
int count = 1000;
int[] arr = new int[count];
Random rd = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rd.nextInt(count);
}
System.out.println(Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}