1. 程式人生 > >插入排序演算法+優化 (二分查詢優化有序部分)C語言實現

插入排序演算法+優化 (二分查詢優化有序部分)C語言實現

直接插入排序
 插入排序思想
        直接插入排序思想是將待排序的陣列看作兩個部分:有序部分和無序部分,排序過程就是不斷將無序部分的元素插入到有序部分合適的位置上,使有序部分元素不斷增加而無序部分資料不斷減少,直到陣列全部有序為止。
        假設陣列A[0...n-1]
        (1)初始時,A[0]作為有序部分,A[1...n-1]為無序部分;
        (2)在有序部分進行比較和移動,為無序部分的第一個元素A[1]找到合適的位置,並插入到有序部分,使A[0,1]構成新的有序部分,而A[2...n-1]為剩下的無序部分;

        (3)按照步驟(2)執行,直到陣列有序。

插入排序的優化
        由插入排序的特點可知,在陣列有序部分進行比較和查詢待排元素的合適位置時,除了簡單的由右向左的順序遍歷外,在通常情況下可以採用效率更高的二分查詢方法找到該位置,此時查詢的時間複雜度降低。但是需要注意的是:雖然比較和查詢時間複雜度降低,但是每次需要移動的元素個數與順序比較和查詢是相同的。實現程式碼(C語言實現)如下。

void binarySearch(int *a,int len)
{
    int i,value,j;
    int low=0,high=0;
    int mid;
    for(i=1;i<len;i++)
    {
        value=a[i];
        low=0;
        high=i-1;
        while(low<=high)
        {
            mid=(low+high)>>1;
            if(a[mid]<value)
            {
                low=mid+1;
            }
            else
            {
                high=mid -1;
            }
        }
        for(j=i-1;j>=low;j--)
        {
            a[j+1]=a[j];
        }
        a[low]=value;
    }
    for(i=0;i<len;i++)
    {
        printf("%d   ",a[i]);
    }
}
int main()
{
    int a[]={98,52,12,456,953,65447,852,462,1532};
    binarySearch(a,9);
    return 0 ;
}

插入排序的效能
         時間複雜度:直接插入排序的最好情況是待排序列已經是升序排列了,在這種情況下,每次只需要進行一次比較操作(一共需要n-1次),不需要移動元素操作,此時時間複雜度為O(n)。而最壞情況是待排序列是降序排列的,此時每次需要進行i次比較和i次移動,i從1到n-1,所以一共需要n(n-1)/2次,此時時間複雜度為O(n^2)。平均來說插入排序演算法複雜度為O(n^2)。
        空間複雜度:僅需要一個輔助變數,所以為O(1);
        穩定性:穩定的就地排序(穩定性還需要程式碼設計來保證);
        使用場合:插入排序不適合對於資料量比較大的排序應用。但是,如果需要排序的資料量很小,例如,量級小於千,那麼插入排序還是一個不錯的選擇,而且,如果待排資料已經是基本有序的,那麼插入排序將是一個絕佳的選擇(為什麼?見時間複雜度分析)。 插入排序在工業級庫中也有著廣泛的應用,
在STL的sort演算法和stdlib的qsort演算法中,都將插入排序作為快速排序的補充,用於少量元素的排序(通常為8個或以下)