數據結構之直接插入排序(二)

排序思路:每次將一個待排序的元素與已排序的元素進行逐一比較,直到找到合適的位置按大小插入。
這裏寫圖片描述

算法實現:

 public void directInsert(int[] datas) {
        int flag = 0, temp = 0;
        for (int i = 1; i < datas.length; i++) {
            // 在 datas[0,1,.....i-1] 中找到合適的位置
            for (int j = i - 1; j >= 0; j--) {
                if (datas[j] < datas[i]) {   // 找到  第一個比datas[i] 小的
                    flag = j;
                    break;
                }
            }
            if (flag != i - 1) {  //如果沒有 進入循環的話  就說明 datas[i-1] < datas[i]    那樣的話  不用調  順序 直接進行下一個了i++
                temp = datas[i];
                for (int j = i - 1; j > flag; j--) {
                    datas[j + 1] = datas[j];
                }
                datas[flag] = temp;
            }
        }

        for (int i = 0; i < datas.length; i++) {
            System.err.printf("data[%d]是:%d %n", i, datas[i]);
        }

    }

進一步優化 :將搜索和數據後移這二個步驟合併。

 public void directInsertSort(int[] datas) { //  將搜索   和數據 後移 合併到一塊

        for (int i = 1; i < datas.length; i++) {
            if (datas[i - 1] > datas[i]) {
                int j = 0;
                for (j = i - 1; datas[j] < datas[i] && j >= 0; j--) {
                    datas[j + 1] = datas[j];
                }
                datas[j + 1] = datas[i];
            }
        }

        for (int i = 0; i < datas.length; i++) {
            System.err.printf("data[%d]是:%d %n", i, datas[i]);
        }
    }

在進一步優化:再對將datas[j]插入到前面datas[0…j-1]的有序區間所用的方法進行改寫,用數據交換代替數據後移。

 public void directInsertSortSwap(int[] datas) {   //  將 後移 改成  交換
        for (int i = 1; i < datas.length; i++) {
            for (int j = i - 1; j >= 0 && datas[j] > datas[j + 1]; j--) {
                datas[j] = datas[j] ^ datas[j + 1];
                datas[j + 1] = datas[j] ^ datas[j + 1];
                datas[j] = datas[j] ^ datas[j + 1];
            }
        }

        for (int i = 0; i < datas.length; i++) {
            System.err.printf("data[%d]是:%d %n", i, datas[i]);
        }
    }

算法分析:
1.當元素的初始序列爲正序時,僅外循環要進行n-1趟排序且每一趟只進行一次比較,沒有進入if語句不存在元素之間的交換(移動)。此時比較次數(Cmin)和移動次數(Mmin)達到 最小值。 Cmin = n-1 Mmin = 0; 此時時間複雜度爲O(n)。
2.當元素的初始序列爲反序時,每趟排序中待插入的元素都要和[0,i-1]中的i個元素進行比較且要將這i個元素後移(arr[j+1] = arr[j]),i個元素後移移動次數當然也就爲i 了,再加上temp = arr[i]與arr[j+1] = temp的兩次移動,每趟移動的次數爲i+2,此時比較次數(Cmin)和移動次數(Mmin)達到最小值。 Cmax = 1+2+…+(n-1) = n*(n-1)/2 = O(n2) Mmax = (1+2)+(2+2)+…+(n-1+2) = (n-1)*(n+4)/2 = O(n2) (i取值範圍1~n-1)此時時間複雜度爲O(n2)。
3..在整個排序結束後,即使有相同元素它們的相對位置也沒有發生變化,
如:5,3,2,3排序過程如下
A–3,5,2,3
B–2,3,5,3
C–2,3,3,5
排序結束後兩個元素3的相對位置沒有發生改變,所以直接插入排序是一種穩定排序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章