十大经典排序算法之插入排序及其二分优化
一、插入排序的實現
1.什么是插入排序呢
插入排序的工作方式像許多人排序一手撲克牌。開始時,我們的左手為空并且桌子上的牌面向下。然后,我們每次從桌子上拿走一張牌并將它插入左手中正確的位置。為了找到一張牌的正確位置,我們從右到左將它與已在手中的每張牌進行比較。拿在左手上的牌總是排序好的,原來這些牌是桌子上牌堆中頂部的牌
2.具體步驟
第一輪:從第二位置的 6 開始比較,比前面 7 小,交換位置。
第二輪:第三位置的 9 比前一位置的 7 大,無需交換位置。
第三輪:第四位置的 3 比前一位置的 9 小交換位置,依次往前比較。
第四輪:第五位置的 1 比前一位置的 9 小,交換位置,再依次往前比較。
…
就這樣依次比較到最后一個元素。
3.使用循環不變式證明算法的正確性
循環不變式的概念:
簡單了說就是每次循環都有某種性質,且該性質一直保持不變,直到循環結束。
循環不變式的三個性質:
1.初始化:循環的第一次迭代之前,它為真。
2.保持:如果循環的某次迭代之前它為真,那么下次迭代之前它仍為真。
3.終止:在循環終止時,不變式為我們提供一個有用的性質,該性質有助于證明算法時正確的。
對于插入排序,如何證明這三個性質
初始化:插入排序初始只有1個元素arr[0],所以該子數組是有序的
保持:每次插入元素到子數組中,該子數組一直保持有序性
終止:循環的終止條件是遍歷到了最后一個將要插入的元素,此時插入過后,子數組已經擁有了原數組的所有數據,且保持有序
因此算法正確。
4.插入排序代碼實現
import java.util.Arrays;/*** @author:抱著魚睡覺的喵喵* @date:2021/2/23* @description: 插入排序*/ public class InsertSort {public static void main(String[] args) {int arr[] = {9,1,4,2,8};InsertSort(arr);System.out.println(Arrays.toString(arr));}public static void InsertSort(int[] arr) {for (int i = 1; i < arr.length; i++) {int insertVal = arr[i];int insertIndex =i - 1;while (insertIndex >= 0 && insertVal < arr[insertIndex]) {arr[insertIndex + 1] = arr[insertIndex];insertIndex--;}arr[insertIndex + 1] = insertVal;}} }5.插入排序算法的分析
1.時間復雜度:最壞的情況就是原數組的數據是降序排列,最好的情況當然就是已經有序(升序)
最壞的情況:O(n^2)
最好的情況:O(n)
所以平均時間復雜度位O(n^2)
2.空間復雜度:O(1)
3.插入排序是穩定的;適用場景:數據規模較小
二、插入排序的優化
于插入排序,如果比較操作的代價比交換操作大的話,可以采用二分查找法來減少比較操作的次數。
1.二分查找算法概述(折半查找法):
二分查找的基本思想是將n個元素分成大致相等的兩部分,取a[n/2]與x做比較,如果x=a[n/2],則找到x,算法中止;如果x<a[n/2],則只要在數組a的左半部分繼續搜索x,如果x>a[n/2],則只要在數組a的右半部搜索x.
2.代碼實現
import java.util.Arrays;/*** @author:抱著魚睡覺的喵喵* @date:2021/3/4* @description: 使用二分法優化直接插入*/ public class DichotomizeInsertSort {public static void main(String[] args) {int arr[] = {2, 5, 8, -11, 6,-19, 7, 8};InsertSort(arr);System.out.println(Arrays.toString(arr));}public static void InsertSort(int arr[]) {int insertValue,mid = 0;int i,j,insertIndex;for (int k = 1; k < arr.length; k++) {i = 0;insertIndex = k;j = k - 1;insertValue = arr[k];while (i <= j) {mid = (i + j) / 2;if (arr[mid] < insertValue) {i = mid + 1;} else {j = mid - 1;}}for (int s = insertIndex - 1; s >= i; s--) {arr[s + 1] = arr[s];}arr[i] = insertValue;}}}3.復雜度分析
時間復雜度:O(n^2)
二分插入排序只是減少了比較的次數,而數據的移動次數還是不變的;
本質上來說:直接插入排序和二分插入排序性能上差不了多少
總結
以上是生活随笔為你收集整理的十大经典排序算法之插入排序及其二分优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用回溯算法分析八皇后问题
- 下一篇: 十大经典排序算法之冒泡排序及其优化