問:你寫一個排序演演算法吧,順便說一下其他的方式,可以吧?
題目:對陣列 {1,3,6,1,8,22,0,1}進行排序
答:
public static void main(String[] args) { String[] arr = {"1", "1", "7", "3", "9", "11", "7"}; Arrays.sort(arr); for (String i : arr) { System.out.println(i); } }
問:首先,你上面程式碼是有問題的,你執行下排序結果,是不對的,既不是升序也不是降序!如果想實現排序你首先需要將字串陣列轉成真正的Integer陣列,才能使用Arrays.sort
答:好的知道了
問:那我再問你,Arrays.sort 這個方法針對 String型別的陣列和Integer型別的陣列有啥區別,String是透過什麼排序的?
答:Integer呢就是透過數字的大小進行比較排序的,String的比較是透過Compare方法,透過檢視Compare原始碼,我發現,它底層是將兩個字串儲存在char型別陣列中,選擇最短的一個字串,然後從第一位遍歷兩個陣列,返回第一個不相同字元的ASCII碼(十進位制)相減的結果;
"abcd".compareTo("adef")== -2 "abc".compareTo("abcdef")== -3 "abc".compareTo("abc") == 0
問:不對啊,小夥子,上面你直接用函式實現的,能不能自己寫個演演算法實現一下?
答:可以的~那我寫一個冒泡:
public static void main(String[] args) { int temp; Integer[] arr = {1, 1, 7, 3, 9, 11, 7}; for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } for (Integer i : arr) { System.out.print(i + "->"); } }
我再來一個快速排序:
public static void quickSort(int[] a, int l, int r) { if (l < r) { int i,j,x; i = l; j = r; x = a[i]; while (i < j) { while(i < j && a[j] > x) j--; // 從右向左找第一個小於x的數 if(i < j) a[i++] = a[j]; while(i < j && a[i] < x) i++; // 從左向右找第一個大於x的數 if(i < j) a[j--] = a[i]; } a[i] = x; quickSort(a, l, i-1); /* 遞迴呼叫 */ quickSort(a, i+1, r); /* 遞迴呼叫 */ } } public static void main(String[] args) { int i; int a[] = {30,40,60,10,20,50}; System.out.printf("before sort:"); for (i=0; i<a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); quickSort(a, 0, a.length-1); System.out.printf("after sort:"); for (i=0; i<a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); }
問:好的,你真棒,你能說下這兩種排序演演算法的區別嗎?或者說在效能上哪種更好?
答:快排的時間複雜度一般是O(nlogn),而氣泡排序的時間複雜度是O(n^2),所以在排序資料量較大的情況下,快排的效能比氣泡排序更好。快排的優勢是更快的速度,更少的比較次數和交換次數。
在JVM層面,快速排序使用了遞迴演演算法,它透過比較陣列中的元素,並將陣列分為兩個子陣列,遞迴排序每個子陣列,最後合併結果。因為每次排序只需要比較一個元素,所以快速排序的複雜度是O(nlogn),比氣泡排序(O(n^2))等其他排序演演算法要快得多。
JVM會管理記憶體的使用,並自動執行垃圾回收,以確保快速排序不會因記憶體不足而停止。因此,在JVM上執行快速排序是一種高效的方法。