1.插入排序(Insertion Sort)基本思想
- 把n個待排序的元素看成為一個有序表和一個無序表
- 開始時有序表中只包含一個元素,無序表中包含有n-1個元素
- 排序過程中每次從無序表中取出第一個元素,把它的排序碼依次與有序表元素的排序碼進行比較,將它插入到有序表中的適當位置
- 使之成為新的有序表。
插入排序的時間復雜度為:O(n2)
2.圖解
3. 代碼實現
1)循環實現
//插入排序 public static void insertSort(int[] arr) { int insertVal = 0; int insertIndex = 0; for(int i = 1; i < arr.length; i++) { //定義待插入的數 insertVal = arr[i]; insertIndex = i - 1; // 即arr[1]的前面這個數的下標 // 給insertVal 找到插入的位置 // 說明 // 1. insertIndex >= 0 保證在給insertVal 找插入位置,不越界 // 2. insertVal < arr[insertIndex] 待插入的數,還沒有找到插入位置 // 3. 就需要將 arr[insertIndex] 后移 while (insertIndex >= 0 && insertVal < arr[insertIndex]) { arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex] insertIndex--; } // 當退出while循環時,說明插入的位置找到, insertIndex + 1 //這里我們判斷是否需要賦值 if(insertIndex + 1 != i) { arr[insertIndex + 1] = insertVal; } } }
2)逐步推導:
{101, 34, 119, 1}
第1輪 {101, 34, 119, 1}; => {34, 101, 119, 1}
{101, 34, 119, 1}; => {101,101,119,1}
{101,101,119,1}; => {34,101,119,1}
第2輪 {34, 101, 119, 1}; => {34, 101, 119, 1}
第3輪 {34, 101, 119, 1}; => {1, 34, 101, 119}
{34, 101, 119, 1}; => {34, 101, 119, 119}
{34, 101, 119, 119}; => {34, 101, 101, 119}
{34, 101, 101, 119}; => {34, 34, 101, 119}
{34, 34, 101, 119}; => {1, 34, 101, 119}

//使用逐步推導的方式來講解,便利理解 //第1輪 {101, 34, 119, 1}; => {34, 101, 119, 1} //{101, 34, 119, 1}; => {101,101,119,1} //定義待插入的數 int insertVal = arr[1]; int insertIndex = 1 - 1; //即arr[1]的前面這個數的下標 //給insertVal 找到插入的位置 //說明 //1. insertIndex >= 0 保證在給insertVal 找插入位置,不越界 //2. insertVal < arr[insertIndex] 待插入的數,還沒有找到插入位置 //3. 就需要將 arr[insertIndex] 后移 while(insertIndex >= 0 && insertVal < arr[insertIndex] ) { arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex] insertIndex--; } //當退出while循環時,說明插入的位置找到, insertIndex + 1 //舉例:理解不了,我們一會 debug arr[insertIndex + 1] = insertVal; System.out.println("第1輪插入"); System.out.println(Arrays.toString(arr)); //第2輪 insertVal = arr[2]; insertIndex = 2 - 1; while(insertIndex >= 0 && insertVal < arr[insertIndex] ) { arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex] insertIndex--; } arr[insertIndex + 1] = insertVal; System.out.println("第2輪插入"); System.out.println(Arrays.toString(arr)); //第3輪 insertVal = arr[3]; insertIndex = 3 - 1; while (insertIndex >= 0 && insertVal < arr[insertIndex]) { arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex] insertIndex--; } arr[insertIndex + 1] = insertVal; System.out.println("第3輪插入"); System.out.println(Arrays.toString(arr));
3)時間測試
public static void main(String[] args) { //int[] arr = {101, 34, 119, 1, -1, 89}; // 創建要給80000個的隨機的數組 int[] arr = new int[80000]; for (int i = 0; i < 80000; i++) { arr[i] = (int) (Math.random() * 8000000); // 生成一個[0, 8000000) 數 } System.out.println("插入排序前"); Date data1 = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date1Str = simpleDateFormat.format(data1); System.out.println("排序前的時間是=" + date1Str); insertSort(arr); //調用插入排序算法 Date data2 = new Date(); String date2Str = simpleDateFormat.format(data2); System.out.println("排序前的時間是=" + date2Str); //System.out.println(Arrays.toString(arr)); }