數據結構與算法之排序算法(一):插入排序

插入排序能夠分爲:直接插入排序和希爾排序(已知元素,找位置)
1.直接插入排序

原理:將一個未排序數組分爲無序區和有序區,不斷將無序區的第一個元素按照大小插入到有序區,最後直到無序區的元素都插入到有序區,排序完成。算法

代碼實現:
for(int i = 1; i < a.length; i++){ //無序區開始下標
    if(a[i] < a[i-1]){//判斷是否應排序
        int currentValue = a[i];//將a[i]臨時存儲起來
        int j = i-1;
        //兩個條件的順序不能變,當j=0時,j--後爲-1,若是先判斷a[j],則會出現數組越界
        while(j >= 0 && a[j] > currentValue){
            a[j+1] = a[j]; //移位
            j--;
        }
        a[j+1] = currentValue; 
    }
}

分析:穩定(無跳躍),空間複雜度O(1),時間複雜度【最佳O(n),平均、最差O(n*n)】 優勢:適用於(1)數組基本有序(2)數據量小數組

 
2.希爾排序(直接插入排序的改進算法,利用了它的兩個優勢)

原理:將數據按照不一樣的增量(步長)分紅多個組,對每一個組分別進行直接插入排序。當剛開始元素很無序的時候,增量最大,分的組最多,每一個組內進行直接插入排序的元素最少,速度很快;當元素基本有序時(小的在前,大的在後),增量很小,直接插入排序對於基本有序的序列效率很高。spa

代碼實現:
for(int gap = a.length / 2; gap >= 1; gap /= 2){//取增量gap爲數組長度的一半,依次取當前的一半,最後爲1
    //把距離爲gap的元素編爲一組,掃描全部組
    for(int i = gap; i < a.length; i++){
        int tmp = a[i];//臨時存儲當前值,爲交換後使用
        for(int j = i - gap; j >=0 && tmp < a[j]; j -= gap){//對距離爲gap的元素進行排序
            a[j + gap] = a[j];
        }
        a[j] = tmp;
    }
}

分析:不穩定(有跳躍,交換的時候後面的可能到前面了),空間複雜度O(1),時間複雜度【取決於增量的選取,在O(nlogn)~O(n*n)之間】code

相關文章
相關標籤/搜索