首先要知道數組中的排序有升序和降序,(這就需要去好好看看數據結構的排序方法原理了)
排序方法對應的有冒泡排序法,快速排序法,選擇排序法,直接插入排序法等方法
我們先搞明白這些排序方法的思想和基本原理,然后再去看代碼應該怎么寫。下面一一介紹。
(一)排序
(1)升序
使用 java.util.Arrays 類中的 sort() 方法對數組進行升序分為以下兩步:
- 導入 java.util.Arrays 包。
- 使用 Arrays.sort(數組名) 語法對數組進行排序,排序規則是從小到大,即升序。
例1:假設在數組 scores 中存放了 5 名學生的成績,現在要實現從低到高排列的功能。在這里使用 Arrays.sort() 方法來實現,具體代碼如下:
public static void main(String[] args) { // 定義含有5個元素的數組 double[] scores = new double[] { 78, 45, 85, 97, 87 }; System.out.println("排序前數組內容如下:"); // 對scores數組進行循環遍歷 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i] + "\t"); } System.out.println("\n排序后的數組內容如下:"); // 對數組進行排序 Arrays.sort(scores); // 遍歷排序后的數組 for (int j = 0; j < scores.length; j++) { System.out.print(scores[j] + "\t"); } }
如上述代碼所示,要對一個數組進行升序排列,只需要調用 Arrays.sort() 方法即可。運行后的輸出結果如下所示。
排序前數組內容如下: 78.0 45.0 85.0 97.0 87.0 排序后的數組內容如下: 45.0 78.0 85.0 87.0 97.0
(2)降序
使用 sort 實現降序有兩種方法,簡單了解即可。
1)利用 Collections.reverseOrder() 方法(Collections 是一個包裝類。大家可以學習《Java Collections類》一節詳細了解):
public static void main(String[] args) { Integer[] a = { 9, 8, 7, 2, 3, 4, 1, 0, 6, 5 }; // 數組類型為Integer Arrays.sort(a, Collections.reverseOrder()); for (int arr : a) { System.out.print(arr + " "); } }
輸出結果如下:
9 8 7 6 5 4 3 2 1 0
2)實現 Comparator 接口的復寫 compare() 方法,代碼如下:
public class Test { public static void main(String[] args) { /* * 注意,要想改變默認的排列順序,不能使用基本類型(int,double,char)而要使用它們對應的類 */ Integer[] a = { 9, 8, 7, 2, 3, 4, 1, 0, 6, 5 }; // 定義一個自定義類MyComparator的對象 Comparator cmp = new MyComparator(); Arrays.sort(a, cmp); for (int arr : a) { System.out.print(arr + " "); } } } // 實現Comparator接口 class MyComparator implements Comparator<Integer> { @Override public int compare(Integer o1, Integer o2) { /* * 如果o1小於o2,我們就返回正值,如果o1大於o2我們就返回負值, 這樣顛倒一下,就可以實現降序排序了,反之即可自定義升序排序了 */ return o2 - o1; } }
輸出結果如下所示。
9 8 7 6 5 4 3 2 1 0
注意:使用以上兩種方法時,數組必須是包裝類型,否則會編譯不通過。
(二)排序方法
(1)冒泡排序法(http://c.biancheng.net/view/927.html)
基本原理:
-
比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
-
對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
-
針對所有的元素重復以上的步驟,除了最后一個。
-
持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
優化:
-
針對問題:
-
方案:
特點:冒泡排序的算法比較簡單,排序的結果穩定,但時間效率不太高。
例1:(http://c.biancheng.net/view/6506.html)
假設待排序序列為 (5,1,4,2,8),如果采用冒泡排序對其進行升序(由小到大)排序,則整個排序過程如下所示:
1) 第一輪排序,此時整個序列中的元素都位於待排序序列,依次掃描每對相鄰的元素,並對順序不正確的元素對交換位置,整個過程如圖 1 所示。
2) 第二輪排序,此時待排序序列只包含前 4 個元素,依次掃描每對相鄰元素,對順序不正確的元素對交換位置,整個過程如圖 2 所示。
3) 第三輪排序,此時待排序序列包含前 3 個元素,依次掃描每對相鄰元素,對順序不正確的元素對交換位置,整個過程如圖 3 所示。
4) 第四輪排序,此時待排序序列包含前 2 個元素,對其進行冒泡排序的整個過程如圖 4 所示。
5) (優化后,這一步不需要了)當進行第五輪冒泡排序時,由於待排序序列中僅剩 1 個元素,無論再進行相鄰元素的比較,因此直接將其並入已排序序列中,此時的序列就認定為已排序好的序列(如圖 5 所示)
例 2
獲取用戶在控制台輸入的 5 個成績信息,將這些成績保存到數組中,然后對數組應用冒泡排序,並輸出排序后的結果,實現步驟如下。
(1) 創建一個 Test24 類文件,在 main() 方法中開始編碼。首先創建 Scanner 類的實例后聲明 double 類型的 score 數組,然后接收用戶在控制台輸入的成績,並保存到元素中。代碼如下:
public static void main(String[] args) { Scanner scan = new Scanner(System.in); double[] score = new double[5]; for (int i = 0; i < score.length; i++) { System.out.print("請輸入第 " + (i + 1) + " 個成績:"); score[i] = scan.nextDouble(); } }
(2) 在對 score 數組排序之前,首先輸出數組中各個元素的值。代碼如下:
System.out.println("排序前的元素值:"); for(double val:score) { System.out.print(val+"\t"); } System.out.println();
(3) 通過冒泡排序方法實現對 score 數組的排序,在實現時需要借助一個臨時變量。代碼如下:
public static void main(String[] args) { System.out.println("通過冒泡排序方法對數組進行排序:"); for (int i = 0; i < score.length - 1; i++) { // 比較相鄰兩個元素,較大的數往后冒泡 for (int j = 0; j < score.length - 1 - i; j++) { if (score[j] > score[j + 1]) { double temp = score[j + 1]; // 把第一個元素值保存到臨時變量中 score[j + 1] = score[j]; // 把第二個元素值轉移到第一個元素變量中 score[j] = temp; // 把臨時變量(第一個元素的原值)保存到第二個元素中 } System.out.print(score[j] + " "); // 對排序后的數組元素進行輸出 } System.out.print("【"); for (int j = score.length - 1 - i; j < score.length; j++) { System.out.print(score[j] + " "); } System.out.println("】"); } }
(4) 運行前面的代碼進行測試,如下所示。
請輸入第 1 個成績:77 請輸入第 2 個成績:90 請輸入第 3 個成績:68 請輸入第 4 個成績:59 請輸入第 5 個成績:80 排序前的元素值: 77.0 90.0 68.0 59.0 80.0 通過冒泡排序方法對數組進行排序: 77.0 68.0 59.0 80.0 【90.0 】 68.0 59.0 77.0 【80.0 90.0 】 59.0 68.0 【77.0 80.0 90.0 】 59.0 【68.0 77.0 80.0 90.0 】
(2)快速排序法(http://c.biancheng.net/view/929.html)
基本原理:
例1:利用快速排序法對一數組進行排序
(1) 聲明靜態的 getMiddle() 方法,該方法需要返回一個 int 類型的參數值,在該方法中傳入 3 個參數。代碼如下:
public static int getMiddle(int[] list, int low, int high) { int tmp = list[low]; // 數組的第一個值作為中軸(分界點或關鍵數據) while (low < high) { while (low < high && list[high] > tmp) { high--; } list[low] = list[high]; // 比中軸小的記錄移到低端 while (low < high && list[low] < tmp) { low++; } list[high] = list[low]; // 比中軸大的記錄移到高端 } list[low] = tmp; // 中軸記錄到尾 return low; // 返回中軸的位置 }
(2) 創建靜態的 unckSort() 方法,在該方法中判斷 low 參數是否小於 high 參數,如果是則調用 getMiddle() 方法,將數組一分為二,並且調用自身的方法進行遞歸排序。代碼如下
public static void unckSort(int[] list,int low,int high) { if(low < high) { int middle = getMiddle(list,low,high); // 將list數組一分為二 unckSort(list,low,middle-1); // 對低字表進行遞歸排序 unckSort(list,middle+1,high); // 對高字表進行遞歸排序 } }
(3) 聲明靜態的 quick() 方法,在該方法中判斷傳入的數組是否為空,如果不為空,則調用 unckSort() 方法進行排序。代碼如下:
public static void quick(int[] str) { if(str.length > 0) { // 查看數組是否為空 unckSort(str,0,str.length-1); } }
(4) 在 main() 方法中聲明 int 類型的 number 數組,接着輸出該數組中的元素。然后調用自定義的 quick() 方法進行排序,排序后重新輸出數組中的元素。代碼如下:
int[] number={13,15,24,99,14,11,1,2,3}; System.out.println("排序前:"); for(int val:number) { System.out.print(val+" "); } quick(number); System.out.println("\n排序后:"); for(int val:number) { System.out.print(val +" "); }
運行前面的代碼進行測試,輸出結果如下:
排序前: 13 15 24 99 14 11 1 2 3 排序后: 1 2 3 11 13 14 15 24 99
(3)選擇排序法
工作原理:每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到全部待排序的數據元素排完。
類別
//第一趟選擇排序 13、15、24、1、4、99 //第二趟選擇排序 13、15、4、1、24、99 //第三趟選擇排序 13、1、4、15、24、99 //第四趟選擇排序 4、1、13、15、24、99 //第五趟選擇排序 1、4、13、15、24、99
例2:代碼。利用選擇排序方法通過編程的方式實現對 number 數組的排序,並輸出已排序的數組元素。
int[] number = {13,15,24,99,4,1}; String end = "\n"; int index; for (int i = 1;i < number.length;i++) { index = 0; for(int j = 1;j <= number.length-i;j++) { if (number[j] > number[index]) { index = j; // 查找最大值 } } end = number[index] + " " + end; // 定位已排好的數組元素 int temp = number[number.length-i]; number[number.length-1] = number[index]; number[index] = temp; System.out.print("【"); for (int j = 0;j < number.length-i;j++) { System.out.print(number[j]+" "); } System.out.print("】"+end); }
結果:
【13 15 24 1 4 】99 【13 15 4 1 】24 99 【13 1 4 】15 24 99 【4 1 】13 15 24 99 【1 】4 13 15 24 99
(4)直接插入排序法
基本思想:將 n 個有序數存放在數組 a 中,要插入的數為 x,首先確定 x 插在數組中的位置 p,然后將 p 之后的元素都向后移一個位置,空出 a(p),將 x 放入 a(p),這樣可實現插入 x 后仍然有序。
例 1:本例子通過直接插入的方法對上述例子中的 number 數組進行排序。創建一個 Test27 類文件,在 main() 方法中開始編碼,具體實現代碼如下:
public static void main(String[] args) { int[] number = { 13, 15, 24, 99, 4, 1 }; System.out.println("排序前:"); for (int val : number) { // 遍歷數組元素 System.out.print(val + " "); // 輸出數組元素 } int temp, j; for (int i = 1; i < number.length; i++) { temp = number[i]; for (j = i - 1; j >= 0 && number[j] > temp; j--) { number[j + 1] = number[j]; } number[j + 1] = temp; } System.out.println("\n排序后:"); for (int val : number) { // 遍歷數組元素 System.out.print(val + " "); // 輸出數組元素 } }
運行結果:
排序前: 13 15 24 99 4 1 排序后: 1 4 13 15 24 99