排序算法總結之插入排序

一,插入排序介紹html

 插入排序是基於比較的排序。所謂的基於比較,就是經過比較數組中的元素,看誰大誰小,根據結果來調整元素的位置。算法

所以,對於這類排序,就有兩種基本的操做:①比較操做; ②交換操做數組

其中,對於交換操做,能夠優化成移動操做,即不直接進行兩個元素的交換,仍是用一個樞軸元素(tmp)將當前元素先保存起來,而後執行移動操做,待肯定了最終位置後,再將當前元素放入合適的位置。(下面的插入排序就用到了這個技巧)--由於,交換操做須要三次賦值,而移動操做只須要一次賦值數據結構

有些排序算法,比較次數比較多,而移動次數比較少,而有些則相反。好比,歸併排序和快速排序,前者移動次數比較多,然後者比較次數比較多。post

 

這裏主要介紹插入排序優化

 

二,插入排序算法分析spa

插入排序算法有種遞歸的思想在裏面,它由N-1趟排序組成。初始時,只考慮數組下標0處的元素,只有一個元素,顯然是有序的。code

而後第一趟 對下標 1 處的元素進行排序,保證數組[0,1]上的元素有序;htm

第二趟 對下標 2 處的元素進行排序,保證數組[0,2]上的元素有序;blog

.....

.....

第N-1趟對下標 N-1 處的元素進行排序,保證數組[0,N-1]上的元素有序,也就是整個數組有序了。

它的遞歸思想就體如今:當對位置 i 處的元素進行排序時,[0,i-1]上的元素必定是已經有序的了。

 

三,插入排序算法實現

 1 public class InsertSort{
 2     
 3     public static <T extends Comparable<? super T>> void insertSort(T[] a){
 4         for(int p = 1; p < a.length; p++)
 5         {
 6             T tmp = a[p];//保存當前位置p的元素,其中[0,p-1]已經有序
 7             int j;
 8             for(j = p; j > 0 && tmp.compareTo(a[j-1]) < 0; j--)
 9             {
10                     a[j] = a[j-1];//後移一位
11             }
12             a[j] = tmp;//插入到合適的位置
13         }
14     }
15     
16     //for test purpose
17     public static void main(String[] args) {
18         Integer[] arr = {34,8,64,51,32,21};
19         insertSort(arr);
20         for (Integer i : arr) {
21             System.out.print(i + " ");
22         }
23     }
24 }

 

四,複雜度分析

 ①插入排序的時間複雜度 就是判斷比較次數有多少,而比較次數與 待排數組的初始順序有關,當待排數組有序時,沒有移動操做(第8行for不成立),此時複雜度爲O(N),當待排數組是逆序時,比較次數達到最大--對於下標 i 處的元素,須要比較 i-1 次。總的比較次數:1+2+...+N-1 ,故時間複雜度爲O(N^2)

①能夠看出,算法中只用到了一個臨時變量(第6行),故空間複雜度爲O(1)

 

其實,插入排序的比較次數與數組的逆序數相關,由於插入排序在將某個元素插入到合適位置時(代碼第12行),其實就是消除這個元素的逆序數。

由定理:N個互異數的數組的平均逆序數是 N(N-1)/4,可知:基於相鄰元素之間的比較和交換的算法的時間複雜度的一個下界爲O(N^2)

比較冒泡排序啊。。。。它採用的思路是:相鄰兩個元素比較,將小的放在前頭。故冒泡排序的時間複雜度爲O(N^2)。。。

基於上面這個定理,另一個排序算法:希爾排序,採用了增量序列。所以,它可能得到一個更好的時間複雜度。

好比,當希爾排序使用Hibbard增量序列時,它的最壞運行時間爲O(N3/2)

 

五,參考資料

各類排序算法的總結

《數據結構與算法分析》MAW著

相關文章
相關標籤/搜索