先来说网上流行最多的实现,用两个指针,一个从前往后,一个从后往前。直接上代码,如下。
1 package com.jeaven; 2 3 public class Solution2 { 4 public void quick_sort(int[] arr, int begin, int end) { 5 if(begin < end) { 6 int mid = partition(arr, begin, end); 7 quick_sort(arr, begin, mid-1); 8 quick_sort(arr, mid+1, end); 9 } 10 } 11 12 13 /* 双向指针的快排思路 14 * 前一个指针指向开始元素begin,第二个指针指向数组倒数第二个end-1,最后一个元素为轴pivot 15 *当arr[i] > pivot时,交换arr[i]和arr[j]然后 j=j-1 16 *当arr[i] < pivot时,就i++ 17 *最终当i和j重合的时候相遇,再将轴归位返回轴的位置,注意下标即可 18 */ 19 public int partition(int[] arr, int begin, int end) { 20 int pivot = arr[end]; 21 int i = begin; 22 int j = end - 1; 23 while(i < j) { 24 if(arr[i] > pivot) { 25 int temp = arr[j]; 26 arr[j] = arr[i]; 27 arr[i] = temp; 28 j--; 29 } else { 30 i++; 31 } 32 } 33 int temp = arr[j+1]; 34 arr[j+1] = arr[end]; 35 arr[end] = temp; 36 return j+1; 37 } 38 39 public static void main(String[] args) { 40 int[] arr = {1,4,2,3,5}; 41 new Solution2().quick_sort(arr, 0, arr.length-1); 42 for(int c : arr) { 43 System.out.print(c + " "); 44 } 45 } 46 }
再来说说我最喜欢的风格,也是算法导论上的快排实现方法,两个指针从同一边开始,算法导论的思路很清晰,还给出了完整的理论推导,不变性的证明,有兴趣的可以去看看算法道路的快排章节。
下面是算法导论关于快排的实现思路,如下:
然后我给出java版本的快排实现:
1 package com.jeaven; 2 3 public class Solution3 { 4 public void quick_sort(int[] arr, int begin, int end) { 5 if(begin < end) { 6 int mid = partition(arr, begin, end); 7 quick_sort(arr, begin, mid-1); 8 quick_sort(arr, mid+1, end); 9 } 10 } 11 12 public int partition(int[] arr, int begin, int end) { 13 int pivot = arr[end]; 14 int i = begin - 1; 15 for(int j = begin; j < end; j++) { 16 if(arr[j] < pivot) { 17 i++; 18 int temp = arr[j]; 19 arr[j] = arr[i]; 20 arr[i] = temp; 21 } 22 } 23 int temp = arr[i+1]; 24 arr[i+1] = arr[end]; 25 arr[end] = temp; 26 return i+1; 27 } 28 29 public static void main(String[] args) { 30 int[] arr = {1,4,2,3,5}; 31 new Solution3().quick_sort(arr, 0, arr.length-1); 32 for(int c : arr) { 33 System.out.print(c + " "); 34 } 35 } 36 }
说明:我喜欢选最后一个元素为轴pivot,当然可以选取数组任意位置为轴,即使分的恨不均匀,但是可以证明除了极端情况,时间复杂度仍然为O(nlgn)。如果选取其他位置作为轴,代码实现的时候可以先将轴和最后一个元素交换位置,这样就可以看成是最后一个位置是轴,就可以很容易实现。