前言
插入排序算法任然需要O(N^2)的時間,但是一般情況下,他要比冒泡排序快一倍,比選擇排序要快一點。
[圖片上傳失敗...(image-39380d-1628999776603)]
一、插入排序
假定排序從中間開始,可以更好的理解插入排序。此時,隊列左邊已經排好序,在隊列中間標記一個元素,在這個作為標記的元素左邊已經是局部有序,(注意,局部有序在冒泡排序和選擇排序中不會出現)這個被標記的元素右邊是未排序的。我們需要做的是在左邊有序的隊列中的適當位置插入被標記的元素。這意味著左邊有序的隊列需要先向右移騰出空間。而被標記的元素需要出列,以提供位移空間。
<font color=#999AAA >示例:pandas 是基于NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。
插入排序的代碼如下:
public void insertionSort(){
int left , right;
for (right = 1;right<arr.length;right++){
int temp = arr[right];
left = right;
while (left>0&&arr[left-1] >=temp){
arr[left] = arr[left-1];
left--;
}
arr[left] = temp;
System.out.println("排序前:"+ Arrays.toString(arr));
}
}
在外層的for循環中,right從變量從1開始,向右移動。它標記了未排序部分的最左端的數據。而內層循環while中,left變量沖right變量開始,向左移動。直到temp變量小于等于left所指的數組數據項,或者它不能再往做移動為止。while中的每一趟都向右移動了一個已排序的數據項。image.png
測試
public class Main {
public static void main(String[] args) {
Random random = new Random();
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(100);
}
System.out.println("排序前:"+Arrays.toString(arr));
InsertSort insertSort = new InsertSort(arr);
insertSort.insertionSort();
System.out.println("排序后:"+Arrays.toString(arr));
}
}
結果:
排序前:[45, 92, 15, 27, 45, 18, 8, 24, 43, 56]
排序前:[45, 92, 15, 27, 45, 18, 8, 24, 43, 56]
排序前:[15, 45, 92, 27, 45, 18, 8, 24, 43, 56]
排序前:[15, 27, 45, 92, 45, 18, 8, 24, 43, 56]
排序前:[15, 27, 45, 45, 92, 18, 8, 24, 43, 56]
排序前:[15, 18, 27, 45, 45, 92, 8, 24, 43, 56]
排序前:[8, 15, 18, 27, 45, 45, 92, 24, 43, 56]
排序前:[8, 15, 18, 24, 27, 45, 45, 92, 43, 56]
排序前:[8, 15, 18, 24, 27, 43, 45, 45, 92, 56]
排序前:[8, 15, 18, 24, 27, 43, 45, 45, 56, 92]
排序后:[8, 15, 18, 24, 27, 43, 45, 45, 56, 92]
總結
在每趟結束時,在將temp位置項插入后,比right變量下標小的數據項都是局部有序的。
在第一趟中,它對多比較一次,第二趟最多比較兩次,一次類推。最后一趟最多,比較N-1次。因此有
然而,因為每趟排序發現插入插入點之前,平均只有全體數據項的一半真的進行了比較,我們chuyi2得到
復制的次數大致等于比較次數,然而,一次復制與一次交換的事件耗費不同,所以相對于隨機數據,這個算法比冒泡排序快一倍,比選擇排序略快。