排序1-快速排序


时间复杂度:O(n*logn),logn是使用分治提高了效率,缺点是越接近有序效率越低,会退化到O(n^2)

      我的实现代码经实测,100万长度数组排序时间平均约为160毫秒

基本思路

  1.基准 对数组选取一个基准数(通常第一个数,提高效率可以取中间的数)

  2.分区 依次比较替换后将数组分为两部分,在基准数位置之前的全部小于基准数,之后的全部大于基准数

  3.递归 对基准数左右两部分子数组递归使用同样的分区方法,直到所有数都确定位置

我的代码实现:

  使用了效率较高的两路快排(亦称填坑法),一个指针从前向后寻找第一个大于基准数的位置,另一个指针从后向前寻找第一个小于基准数的位置,找到后交换位置(基准数的位置先被第一个小于基准数的占用,后面全部交换完成,留下的坑位就是基准数的位置)

 1 public static void sort(int[] arr){
 2         sort(arr,0,arr.length-1);
 3 }
 4 
 5 public static void sort(int[] arr, int left, int right) {
 6         if (left >= right){
 7             return;
 8         }
 9         int p = partition(arr,left,right);
10         sort(arr,left,p-1);
11         sort(arr,p+1,right);
12  }
13 
14 public static int partition(int[] arr, int left, int right) {
15         int base = arr[left];
16         int i = left;
17         int j = right;
18         //一直挖坑到左右指针重合
19         while (i<j){
20             //从右向左找到第一个小于基准值的位置
21             while (arr[j]>base && j>i){
22                 j--;
23             }
24             //找到后填左指针的坑,留下坑位,左指针前进一位(填哪侧的坑,哪测前进,否则就重复填了)
25             if (i<j){
26                 arr[i] = arr[j];
27                 i++;
28             }
29             //从左向右找到第一个大于基准值的位置
30             while (arr[i]j){
31                 i++;
32             }
33             //找到后填右指针的坑,留下坑位,右指针前进一位
34             if(i<j){
35                 arr[j]=arr[i];
36                 j--;
37             }
38         }
39         //循环结束后,i=j,就是基准值的坑位
40         arr[i] = base;
41         return i;
42  }

相关