1 //快排 2 class Solution { 3 public List<Integer> sortArray(int[] nums) { 4 List<Integer> sortArray = new ArrayList<Integer>(); 5 for(int i=0;i<nums.length;i++){ 6 sortArray.add(nums[i]); 7 } 8 if(sortArray.size()>1){ 9 quicksort(sortArray,0,sortArray.size()-1); 10 } 11 12 return sortArray; 13 } 14 public void quicksort(List<Integer> nums,int a,int b){ 15 if(a>=b){ 16 return; 17 } 18 int p = spilt(nums,a,b); 19 quicksort(nums,a,p-1); 20 quicksort(nums,p+1,b); 21 return; 22 } 23 public int spilt(List<Integer> nums,int a,int b){ 24 int i = a-1; 25 int j=a; 26 for(j=a;j<b;j++){ 27 if(nums.get(j)<=nums.get(b)){ 28 i=i+1; 29 swap(i,j,nums); 30 } 31 } 32 i=i+1; 33 swap(i,b,nums); 34 return i; 35 } 36 public void swap(int a,int b,List<Integer> nums){ 37 int c=nums.get(a); 38 nums.set(a,nums.get(b)); 39 nums.set(b,c); 40 } 41 }
解题思路:
分治算法,第一步看是否满足条件,此题中是判断数组左下边是否大于等于右下标,是的话则返回。
第二步进行划分,固定选取数组最后一位为进行划分的元素,采用双指针,当前数组起始位置到第一个指针i值之间[a,i]为已遍历过且小于划分元素的所有数字,第一个指针i+1到第二个指针之间j之间[i+1,j]为已遍历过且大于划分元素的所有数字,第二指针j+1到倒数第二个下标之间[j+1,b-1]为还未遍历的数字。
第三步对划分出的两部分数组分别进行处理,此处需要注意的地方为
19 quicksort(nums,a,p-1); 20 quicksort(nums,p+1,b);
分别处理的时候,一定要去掉划分标记位置p坐标对应的元素,即划分的两个数组分别为[a,p-1],[p+1,b]。试想如果将p放入左边数组中为[a,p],坐标数组中第一个元素至倒数第二个元素都是小于
或等于nums[p]的,这样会陷入无限递归循环中。