寫程式的基本功-排序演算法(Sorting Algorithm)
這裡所稱的排序(Sorting),是指將一串不規則的數值資料(陣列資料)依照遞增或是遞減的方式重新編排。要將一串不規則的數值資料遞增或是遞減排列,方法當然不會只有一種,而排序演算法(Sorting Algorithm)就是排列資料的方法,目前已知的方法有很多,在這篇文章中將會介紹比較容易理解的五種排序演算法,分別是交換排序(Exchange sort)、選擇排序(Selection sort)、插入排序(Insertion sort)、氣泡排序(Bubble sort)和快速排序(Quick sort)。
交換排序法(Exchange Sort)
交換排序是最簡單的排序方法。從第一個數開始逐一和之後的數做比較,如果大於或是小於就交換。直到判斷至資料最尾端,才會回到第二個數重新和之後的數做比較。如此反覆動作後,當已經沒有可以判斷的數時,整個排序法就run完了。
圖解交換排序法
假設現在有個陣列:[69,81,30,38,9,2,47,61,32,79] 要如何將它遞增排列呢?
一開始,位於[索引0]的69,要先跟之後的數(81,30,38…)比大小。因為現在要遞增排列,數值較小的值要放在陣列前面,所以要找到比69還小的值,並且與之交換位置。69和81先比大小,81比69大,不換位置。69再跟30比大小,30比69小,要換位置。如下圖:
此時[索引0]所存放的值就是30,還要再跟[索引3]之後的數比大小。38比30大,不換位置。30再跟9比大小,9比30小,要換位置。如下圖:
此時[索引0]所存放的值又變成9,然後再跟[索引5]的2比大小,又要再換一次位置。
[索引0]所存的值為2,[索引6]之後都找不到比2小的數,此時[索引0]的值可以固定為2。
再來從[索引1]開始往下判斷。69比81小,要交換。
38又比69小,再交換。
30又比38小,再交換。
9又比30小,再交換。
9比後面任何一個數都小,固定不變。繼續從[索引2]重新比大小。
當沒辦法繼續往下比較時,整個排序法就結束了。而且陣列內的數值也成功地變成遞增排列。
交換排序法程式碼(Java)
public static int[] exchange_sort(int[] ori_arr, boolean isIncrease){ //交換排序(Exchange sort) int[] arr=ori_arr.clone(); //將arr陣列位址指向新複製出來的ori_arr陣列。確保原始陣列資料不會改變。 int len=arr.length; //取得陣列長度 for(int i=0;i<len-1;i++){ for(int k=i+1;k<len;k++){ if((isIncrease&&arr[i]>arr[k])||(!isIncrease&&arr[i]<arr[k])){ //遞增遞減判斷 int buffer=arr[i]; arr[i]=arr[k]; arr[k]=buffer; } } } return arr; } |
選擇排序法(Selection Sort)
選擇排序法也是很簡單的排序方法,跟交換排序法類似。不過它的陣列資料交換次數比交換排序法還要少很多。它的作法同樣是從[索引0]開始向右判斷之後索引的值。與交換排序法不同的是,選擇排序法是取出其右段的最小值或最大值(視遞增遞減而定)和[索引0]的值互相對換。詳細圖解因為跟交換排序法極為相似,不再說明,直接看程式碼吧!
選擇排序法程式碼(Java)
public static int[] selection_sort(int[] ori_arr, boolean isIncrease){ //選擇排序(Selection sort) int[] arr=ori_arr.clone(); //將arr陣列位址指向新複製出來的ori_arr陣列。確保原始陣列資料不會改變。 int len=arr.length; //取得陣列長度 for(int i=0;i<len-1;i++){ int temp=i; //儲存最大或是最小值所指向的索引位置 for(int k=i+1;k<len;k++){ if((isIncrease&&arr[temp]>arr[k])||(!isIncrease&&arr[temp]<arr[k])){ //遞增遞減判斷 temp=k; } } if(i!=temp){ //若索引未改變,則交換陣列值 int buffer=arr[i]; arr[i]=arr[temp]; arr[temp]=buffer; } } return arr; } |