1. 交換排序—氣泡排序(Bubble Sort)
基本思想:
排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的倆個數依次進行比較
和調整,讓較大的數下沉,較小的數往上冒。即:每當倆相鄰的數比較後發現他們的排序與排序的要求相反時,就將他們交換。
氣泡排序示例:
演算法的實現:
public class BubbleSort2 { public static void main(String[] args) { int[] a = {12,43,65,72,87,21,98,21,911,679,22,4,1,8,2456,32}; bubbleSort(a,a.length); for(int i=0; i<a.length; i++){ System.out.print(a[i]+" "); } } public static void bubbleSort(int[] a,int n){ int temp; for(int i=0; i<n-1; i++){ for(int j=0; j<n-1-i; j++){ if(a[j] > a[j+1]){ temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } } }
氣泡排序演算法的改進:
對氣泡排序的改進是加入一標誌性變數exchange,用於標誌某一趟排序過程中是否有資料交換,如果進行某一趟排序時,並沒有資料交換,則說明資料已經按要求排列好,可立即結束排序,避免不必要的比較過程,本文提供一下倆種改進演算法:
1、設定一標誌性變數pos,用於記錄每一趟排序過程中最後一交換資料的位置。由於pos位置之後的資料已經按要求排列好了,所以下一趟排序的時候只需要掃描到pos位置即可。
改進後演算法如下:
public class BubbleSort3 { public static void main(String[] args) { int[] a = { 12, 43, 65, 72, 87, 21, 98, 21, 911, 679, 22, 4, 1, 8, 2456, 32 }; bubbleSort(a, a.length); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); } } public static void bubbleSort(int[] a, int n) { int i = n - 1; // 初始時,最後位置保持不變 while (i > 0) { int pos = 0; // 每趟開始時,無記錄交換 for (int j = 0; j < i; j++) { if (a[j] > a[j + 1]) { pos = j; // 記錄交換的位置 int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } i = pos;// 為下一趟排序作準備 } } }
2、傳統氣泡排序每一趟氣泡排序只能找到一個最大值或者最小值,我們考慮利用在每趟排序中進行正向和反向倆遍的冒泡方法一次可以得到倆個值(最大值和最小值),從而使排序趟數幾乎減少一半。
改進後的演算法為:
public class BubbleSort4 { public static void main(String[] args) { int[] a = { 12, 43, 65, 72, 87, 21, 98, 21, 911, 679, 22, 4, 1, 8, 2456, 32 }; bubbleSort(a, a.length); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); } } public static void bubbleSort(int[] a, int n) { int low = 0; int high = n - 1; int temp, j; while (low < high) { for (j = low; j < high; ++j) { // 正向冒泡,找到最大值 if (a[j] > a[j + 1]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } --high;// 修改high值, 前移一位 for (j = high; j > low; --j) {// 反向冒泡,找到最小者 if (a[j] < a[j - 1]) { temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } ++low;// 修改low值,後移一位 } } }