排序
快排,挖坑填数
public class QuickSort { public int Partition(int[] a,int i, int j){ int x = a[i]; while(i<j){ while(a[j]>x && i<j){ j--; // find the first number lower than x } if(j>i){ a[i] = a[j]; i++; } while(a[i]<x && i<j){ i++; } if(j>i){ a[j] = a[i]; j--; } } a[i] = x; return i; } public void QuickSort(int[] a, int start, int end){ if(start < end){ int i = Partition(a,start,end); //System.out.println(i); QuickSort(a,start,i-1); QuickSort(a,i+1,end); } } public static void main(String args[]){ QuickSort qs = new QuickSort(); int[] a = {5,4,6,8,7,0,9,1,2,3}; qs.QuickSort(a, 0, 9); for(int i=0;i<=9;i++){ System.out.println(a[i]); } } }
对它进行性能分析,最坏的情况,是每次划分后,分出一个长度为n-1,一个长度为1,导致要依次执行n次QuickSort(a,0,n-1),此时时间复杂度为n^2
最好的情况是,每次都是平衡的划分,大于阈值的元素个数约等于小于阈值的元素个数,此时时间递归式是 T(n) = 2T(n/2)+x(n),x(n)是Partition的时间复杂度
此时,时间复杂度是nlg(n)
排序的稳定性:
稳定的排序: 冒泡排序,插入排序,基数排序,归并排序
不稳定的排序:选择排序,快速排序,希尔排序,堆排序
package leetcode; public class Sort { /* * 交换排序, 包括快速排序和冒泡排序 * 快速排序,时间复杂度为O(nlgn) * 冒泡排序,时间复杂度为O(n^2) */ public void QuickSort(int[] nums, int start, int end){ if(start < end){ int i = Partition(nums, start,end); QuickSort(nums,start,i-1); QuickSort(nums,i+1,end); } } public int Partition(int[] nums, int i, int j){ int x = nums[i]; while(i < j){ while(nums[j] > x && i < j){ j--; } if(j > i){ nums[i] = nums[j]; i++; } while(nums[i] < x && i < j){ i++; } if(j > i){ nums[j] = nums[i]; j--; } } nums[i] = x; return i; } public void BubbleSort(int[] nums){ int i,j,tmp,len=nums.length; for(i=0;i<len;i++){ for(j=0;j<len-i-1;j++){ if(nums[j] < nums[j+1]){ tmp = nums[j]; nums[j] = nums[j+1]; nums[j+1] = tmp; } } } } /* * 插入排序,包括直接插入排序和希尔排序 * 直接插入排序,时间复杂度为O(n^2) * 希尔排序,时间复杂度为O(n^2) */ public void InsertSort(int[] nums){ int i,j,tmp; for(i=0;i<nums.length;i++){ for(j=i;j>0;j--){ if(nums[j] > nums[j-1]){ tmp = nums[j]; nums[j] = nums[j-1]; nums[j-1] = tmp; } } } } public void ShellSort(int[] nums){ int i,j,k,gap,tmp,len=nums.length; for(gap=len/2;gap>0;gap=gap/2){ for(i=0;i<gap;i++){ for(j=i+gap;j<len;j+=gap){ if(nums[j] > nums[j-gap]){ tmp = nums[j]; k = j-gap; while(k >=0 && nums[k] < tmp){ nums[k+gap] = nums[k]; k -=gap; } nums[k+gap] = tmp; } } } } } /* * 交换排序,有堆排序和选择排序 * 选择排序,时间复杂度是O(n^2) * 堆排序,时间复杂度是O(nlgn) */ public void SelectSort(int[] nums){ int i,j,min,loc=0,tmp,len=nums.length; for(i=0;i<len;i++){ min = nums[i]; loc = i; for(j=i;j<len;j++){ if(nums[j] < min){ min = nums[j]; loc = j; } } tmp = nums[i]; nums[i] = min; nums[loc] = tmp; } } public static void main(String args[]){ int[] nums = {6,3,1,8}; Sort s = new Sort(); // s.QuickSort(nums, 0, nums.length-1); s.SelectSort(nums); for(int i=0;i<nums.length;i++){ System.out.print(nums[i]+" "); } } }