每天一算法 -- (插入排序)
一、原理
插入排序就是把當前待排序的元素插入到一個已經排好序的列表裏面。對於給定的一組記錄,初始時假定第一個記錄自成一個有序序列,其余記錄為無序序列。接著從第二個記錄開始,按照記錄的大小依次將當前處理的記錄插入到其之前的有序序列中,直到最後一個記錄插到有序序列中為止。
二、思路
1.在要排序的一組數中,假設前面(n-1)[n>=2] 個數已經是排好順序的,現在要把第n個數找到相應位置並插入,使得這n個數也是排好順序的。如此反復循環,直到全部排好順序。
2.例子:假設有一個數組 :{3,1,2,8,7,9}
第一趟:1和3比較,1<3,則將1和3的位置互換,為:
1,3,2,8,7,9
第二趟:2和1、3比較,2<3,則將2和3的位置互換,為:
1,2,3,8,7,9
第三趟:8和1、2、3比較,8>前面的,則位置不變,為:
1,2,3,8,7,9
第四趟:7和1、2、3、8比較,7<8,則7和8的位置互換,為:
1,2,3,7,8,9
第五趟:9和1、2、3、7、8比較,9>前面的,則位置不變,為:
1,2,3,7,8,9
三、時間復雜度
在第一趟排序中,插入排序最多比較一次,第二趟最多比較兩次,依次類推,最後一趟最多比較N-1次,因此有:
1+2+3+...+N-1 = N*N(N-1)/2.
然而,因為在每一趟排序發現插入點之前,平均只有全體數據項的一半真的進行了比較,除以2得到:
N*N(N-1)/4.
復制的次數大致等於比較的次數。然而,一次復制與一次比較的時間耗費不同,所以相對隨機數據,這個算法比冒泡排序快一倍,比選擇排序略快。
在任意情況,對於隨機順序的數據進行排序的時間復雜度為O(n2);對於已經有序或基本有序的數據來說,插入排序要好得多。當數據有序的時候,while循環的條件總是假。所以他就變成了外層循環中的一個簡單語句,執行n-1次,在這種情況下,算法運行只需要O(n)的時間。如果基本有序,插入排序只需要O(n)的時間
四、代碼實現
1 /** 2 * 排序算法 3 * @author Administrator 4 */ 5 public class Sort { 6 7 /** 8 * 插入排序 9 * @param arr 10 */ 11 public static void insertSort(int[] arr){ 12 13 int insert = 0; // 要插入的元素 14 int j = 0; 15 16 for(int i = 1; i < arr.length; i ++){ // 從數組的第二個元素開始循環將數組中的元素插入 17 insert = arr[i]; // 設置數組中的第2個元素為第一次循環要插入的數據 18 j = i - 1; // 與待排序元素值作比較的元素的下標 19 while(j >= 0 && insert < arr[j]){ // 如果要插入的元素小於第j個元素,就將第j個元素向後移動 20 arr[j + 1] = arr[j]; 21 j --; 22 } 23 arr[j + 1] = insert; // 找到了插入的位置,插入 24 } 25 26 for(int i = 0;i < arr.length; i ++){ 27 System.out.print(arr[i] + " "); 28 } 29 } 30 31 /** 32 * 測試 33 * @param args 34 */ 35 public static void main(String[] args) { 36 int[] arr = {3,1,2,8,7,9}; 37 insertSort(arr); 38 } 39 }
每天一算法 -- (插入排序)