Java排序演算法之——氣泡排序,插入排序,選擇排序
<1>氣泡排序 這個名詞的還是很形象的,就是每次比較相鄰的兩個數,大的數總是往後面冒,所以每輪比較結束後,大數都會冒到最後面。 每次比較的結果如下: 無序陣列 :8 2 4 3 5 7 1 9 6 (後面所有的排序都將使用這個陣列) 第一輪比較:2 4 3 5 7 1 8 6 9 第二輪。。:2 3 4 5 1 7 6 8 9 第三輪。。:2 3 4 5 1 6 7 8 9 第四輪。。:2 3 4 1 5 6 7 8 9 第五輪。。:2 3 1 4 5 6 7 8 9 第六輪。。:2 1 3 4 5 6 7 8 9 第七輪。。:1 2 3 4 5 6 7 8 9 我們用程式來描述這種變化: /** * 氣泡排序,預設為從小到大排序 * @param array 需要排序的陣列 */ public static void bubbleSort(int[] array) { int length = array.length; for (int i = 1; i < length; i++) {//外層迴圈表示每一輪的比較,為了便於理解我們將i初始化為1,表示從第一輪開始,也能避免內層迴圈的下標越界 for (int j = 0; j < length-i; j++) {//內層迴圈表示相鄰的兩個數比較,我們同陣列下標一樣,從0開始 if (array[j] > array[j+1]) { int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } } 如果是遞減排序: /** * 氣泡排序 * @param array 需要排序的陣列 * @param pattern 當引數不為空的時候,表示遞減排序 */ public static void bubbleSort(int[] array, String pattern) { if (StringHelper.isEmpty(pattern)) {//isEmpty()這是我自己寫的一個工具類,用於判斷字串是否為null或者空 bubbleSort(array);//當pattern 為空或者為null時候遞增排序 return; } int length = array.length; for (int i = 1; i < length; i++) { for (int j = 0; j < length-i; j++) { if (array[j] < array[j+1]) {//遞減排序的話,那就讓小的往後面冒就行了 int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } }
<2>插入排序 插入排序個人認為是很好理解的一種演算法,實現的話也比較簡單。 對於一個要排序的陣列,我們將第一個數作為有序陣列,然後後面的元素一次插入到這個有序陣列中。 那麼對於無序陣列,他的元素就會分為已經插入的,和尚未插入的。 唯一不好理解的就是,用程式插入時候,移動元素怎麼移動。 我們先看看陣列每次的變化,我們還用上面的無序陣列: 無序陣列 :8 2 4 3 5 7 1 9 6 已插入陣列: 8 尚未插入元素:2 4 3 5 7 1 9 6 已插入陣列: 2 8 尚未插入元素:4 3 5 7 1 9 6 已插入陣列: 2 4 8 尚未插入元素:3 5 7 1 9 6 已插入陣列: 2 3 4 8 尚未插入元素:5 7 1 9 6 已插入陣列: 2 3 4 5 8 尚未插入元素:7 1 9 6 已插入陣列: 2 3 4 5 7 8 尚未插入元素:1 9 6 已插入陣列: 1 2 3 4 5 7 8 尚未插入元素:9 6 已插入陣列: 1 2 3 4 5 7 8 9 尚未插入元素:6 已插入陣列:1 2 3 4 5 6 7 8 9 尚未插入元素: 我們用程式來描述這個插入過程: /** * 插入排序,預設遞增排序 * @param array 要排序的陣列 */ public static void insertSort(int[] array) { int length = array.length; for (int i = 1; i < length; i ++) {//因為第一個我們預設為已經排序了的,所以我們從第二個開始插入,也就是下標為1 int j = i; int temp = array[j]; while (j > 0 && temp < array[j-1]) { array[j] = array[j-1];//我們這裡不需要交換,找到要插入的位置,後面的元素整體後移就行了 j--; } array[j] = temp;//插入到對應的位置 } } 遞減排序: /** * 插入排序 * @param array 待排序陣列 * @param parttern 排序方式,值不為空時候表示遞減排序 * @return 有序陣列 */ public static void insertSort(int [] array, String parttern) { if (StringHelper.isEmpty(parttern)) { insertSort(array); return; }
int j = 0; for (int i = 1; i < array.length; i++) { j = i; int temp = array[i];//記錄要插入的值 while (j >0 && temp > array[j-1]) { array[j] = array[j-1]; j--; } array[j] = temp; } } <3>選擇排序 交換排序的思路是每一輪選出較小元素然後交換。 第一輪交換的時候,找出剩餘9個元素中最小的,和第一個交換; 第二輪交換的時候,找出剩餘8個元素中修小的,和第二個交換; ... 這個和氣泡排序有點類似的,但是演算法實現不一樣。 我們先看交換排序的過程: 無序陣列 :8 2 4 3 5 7 1 9 6 第一輪交換:1 2 4 3 5 7 8 9 6 (8和1交換 ) 第二輪交換:1 2 4 3 5 7 8 9 6 (2不用交換) 第三輪交換:1 2 3 4 5 7 8 9 6 (4和3交換) 第四輪交換:1 2 3 4 5 7 8 9 6 (4不用交換) 第五輪交換:1 2 3 4 5 7 8 9 6 (5不用交換) 第六輪交換:1 2 4 3 5 6 8 9 7 (7和6交換) 第七輪交換:1 2 4 3 5 6 7 9 8 (8和7交換) 第八輪交換:1 2 4 3 5 6 7 8 9 (9和8交換) 我們看程式實現這種演算法: /** * 選擇排序 * @param array 需要排序的陣列 * @param pattern 當傳值不為空時候,遞減排序 */ public static void selectSort(int[] array, String pattern) { if (StringHelper.isEmpty(pattern)) { selectSort(array); return; } int length = array.length; for (int i = 0; i < length; i++) {//外層控制選擇次數 int min = i; for (int j = i+1; j < length; j++) {//選擇出最小元素的下標 if (array[min] < array[j]) { min = j; } } if (i != min) { int temp = array[i]; array[i] = array[min]; array[min] = temp; } } } 遞減排序: /** * 選擇排序,預設遞增排序 * @param array 需要排序的陣列 */ public static void selectSort(int[] array) { int length = array.length; for (int i = 0; i < length; i++) {//外層控制選擇次數 int min = i; for (int j = i+1; j < length; j++) {//選擇出最小元素的下標 if (array[min] > array[j]) { min = j; } } if (i != min) { int temp = array[i]; array[i] = array[min]; array[min] = temp; } } }