1. 程式人生 > >直接插入算法的C++實現

直接插入算法的C++實現

bubuko 所有 優勢 選擇 http 指定 string () 賦值語句

直接插入算法:每趟將一個待排序的關鍵字按照其值的大小插入到已經排好的部分有序序列的適當位置上,直到所有待排序的關鍵字都被插入到有序序列中為止。

理論上,在直接插入排序中第二層循環是可以提前結束的,即某個元素在尋找自己合適位置時並未循環遍歷到序列最前端。

這是直接插入排序和簡單選擇排序最大的不同。也是直接插入排序和簡單選擇排序同為時間復雜度O(n2),但是直接插入排序效率更高的原因。

尤其是在待排序數據基本有序的時候,這種優勢將極其明顯。甚至此時直接插入排序要比時間復雜度為O(nlogn)的排序算法更加高效。

#include<iostream>
#include<string
> using namespace std; template <typename T> void insertSelectionSort(T arr[],int n){ //不用考慮第0個元素,因為插入排序初始情況下,第0個元素自身就是有序的 for(int i=1;i<n;i++){ //尋找arr[i]合適的插入位置 //每次比較的是當前元素和當前元素的前一個元素的比較,故判斷條件是j>0而不是j>=0 for(int j=i;j>0&&arr[j-1]>arr[j];j--) swap(arr[j],arr[j
-1]); } } int main(){ int a[10]={10,9,8,7,6,5,4,3,2,1}; insertSelectionSort(a,10); for(int i=0;i<10;i++) cout<<a[i]<<" "; cout<<endl; float b[3]={3.3f,2.2f,1.1f}; insertSelectionSort(b,3); for(int j=0;j<3;j++) cout<<b[j]<<"
"; cout<<endl; string c[4]={"D","C","B","A"}; insertSelectionSort(c,4); for(int k=0;k<4;k++) cout<<c[k]<<" "; cout<<endl; return 0; }

輸出結果:

技術分享圖片

但是,如果我們進行算法性能測試,我們會發現上面的代碼並未將這種效率高的優勢顯示出來。

原因是在這段代碼中存在大量的數值交換,而每一次數值交換都包括三次賦值的操作,在本例中還包括訪問數組索引所在位置的時間,這些是比簡單的比較耗時更多的存在。

所以我們可以對上面關鍵代碼進行優化。


template <typename T>
void insertSelectionSort(T arr[],int n){

    for(int i=1;i<n;i++){
        //將待排序的關鍵字復制出來,拿它與它前面的元素進行比較
        T e=arr[i];
        //需要把j的定義拿到for循環的外面,因為最後要在索引j指定的位置(比較後的目標位置)插入復制出來的關鍵字e
        int j;    
        for(j=i;j>0&&arr[j-1]>e;j--)
            //將比待排序關鍵字的大的關鍵字依次後移
            arr[j]=arr[j-1];

        arr[j]=e;
    }
}

在這裏我們不再調用swap函數進行數值的交換,而是全都是用賦值語句完成相應的操作。

就大大優化了算法。

需要說明一下的是:對於直接插入排序,一趟排序後並不能確保一個關鍵字到達其最終位置。

直接插入算法的C++實現