package util; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Sort { /** * 歸併排序法 * 傳入的Object數組必須實現了Comparable接口的compareTo方法 * 不然報錯 * 沒有設置多餘的傳入參數,因而需要拷貝數組兩次 * 時間複雜度固定爲 O(n+2nlog2n) * 通過遞歸,將數組按1:1切分,到只有一個元素時,此時數組是排序好的 * 然後通過大小比較組合 * @param arr * @author 風瀟瀟 */ public static void binnerySort(Object[] arr){ if(arr.length>1){ Object[] arr1=Arrays.copyOfRange(arr, 0, arr.length/2); Object[] arr2=Arrays.copyOfRange(arr, arr.length/2, arr.length); binnerySort(arr1); binnerySort(arr2); int n1=0,n2=0; for(int i=0;i<arr.length;i++){ if(n1<arr1.length&&n2<arr2.length){ if(((Comparable)arr1[n1]).compareTo(arr2[n2])<0){ arr[i]=arr1[n1++]; } else{ arr[i]=arr2[n2++]; } } else if(n1<arr1.length){ arr[i]=arr1[n1++]; } else if(n2<arr2.length){ arr[i]=arr2[n2++]; } } } } /** * 利用泛型設置類型檢查 * <T extends Comparable<T>>要求傳入的數組類型必須是可比的即實現了Comparable的compareTo * <T extends Comparable<?super T>>指若T的父類型實現了可比亦可 * 具體實現同歸並排序類似 * @param arr */ public static <T extends Comparable<T>> void sort(T[] arr){ if(arr.length>1){ T[] arr1=Arrays.copyOfRange(arr, 0, arr.length/2); T[] arr2=Arrays.copyOfRange(arr, arr.length/2, arr.length); sort(arr1); sort(arr2); int n1=0,n2=0; for(int i=0;i<arr.length;i++){ if(n1<arr1.length&&n2<arr2.length){ if(((Comparable)arr1[n1]).compareTo(arr2[n2])<0){ arr[i]=arr1[n1++]; } else{ arr[i]=arr2[n2++]; } } else if(n1<arr1.length){ arr[i]=arr1[n1++]; } else if(n2<arr2.length){ arr[i]=arr2[n2++]; } } } } /** * 基於Object[]數組排序實現 * 注意傳入的泛型必須是實現了Comparable * 因無法創建泛型數組,必須通過Object排序後再強轉 * 因而無法添加泛型檢查 * @param list */ public static <T> void sort(List<T> list){ Object[] arr = list.toArray(); binnerySort(arr); for(int i=0;i<arr.length;i++){ list.set(i, (T)arr[i]); } } /** * 數組排序,使用泛型Comparator接口 * 可以通過實現Comparator接口重寫compare方法來界定自己要求的排序 * @param arr * @param com */ public static <T> void sort(Object[] arr ,Comparator<T> com){ if(arr.length>1){ Object[] arr1=Arrays.copyOfRange(arr, 0, arr.length/2); Object[] arr2=Arrays.copyOfRange(arr, arr.length/2, arr.length); sort(arr1,com); sort(arr2,com); int n1=0,n2=0; for(int i=0;i<arr.length;i++){ if(n1<arr1.length&&n2<arr2.length){ if(com.compare((T)arr1[n1],(T)arr2[n2])<0){ arr[i]=arr1[n1++]; } else{ arr[i]=arr2[n2++]; } } else if(n1<arr1.length){ arr[i]=arr1[n1++]; } else if(n2<arr2.length){ arr[i]=arr2[n2++]; } } } } public static <T> void sort(List<T>list ,Comparator<T> com){ Object[] arr = list.toArray(); sort(arr,com); for(int i=0;i<arr.length;i++){ list.set(i, (T)arr[i]); } } public static void main(String[] args){ List<String> list = new ArrayList<String>(); list.add("aaa"); list.add("a"); list.add("abs"); list.add("abcef"); list.add("defg"); sort(list,new StrCompare()); System.out.println(list); } }