直接插入排序以及其改進版-二分法排序

插入排序是一種簡單直觀的排序算法。 序列能夠分爲有序區和無序區,開始時有序區只有第一個元素,而後每次把無序區中第一個元素插入到有序區中。ios

當無序區爲空時,排序結束。算法

那如何把元素插入到有序區中呢?函數

直接插入排序的作法是從後到前逐一比較。總時間複雜度爲O(N^2)。 測試

既然是插入到有序區,那咱們能夠考慮用二分法快速找到應該插入的位置,可是在順序存儲結構中,仍然沒法避免插入過程移動元素的開銷,因此這種方法總時間複雜度仍然是O(N^2)。spa

就當複習一下二分吧.net

參考[1]二分法排序的原理code

算法思想簡單描述: 在插入第i個元素時,對前面的0~i-1元素進行折半,先跟他們 中間的那個元素比,若是小,則對前半再進行折半,不然對後半 進行折半,直到left>right,而後再把第i個元素前1位與目標位置之間 的全部元素後移,再把第i個元素放在目標位置上。blog

具體代碼以下:排序

#include<iostream>
#include <stdio.h>
#include<vector>
using  namespace std;
//函數模版,打印vector中的內容
template <typename T>
void printVector(const vector<T>&v)
{
    if(v.empty())   cout<<endl<<"your vector is empty"<<endl;
    cout<<endl;
    for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<" ";
    }
    cout<<endl;
}
//1. 直接插入排序
vector<int> insertSort(vector<int> v)
{
    if(v.empty()) return v;
    int t=0;
    int n=v.size()-1;
    for(int i=1;i<=n;i++)
    {
        if(v[i]<v[i-1])
        {
            int t=v[i];
            int j=i-1;
            for(;j>=0 && v[j]>t;j--)    v[j+1]=v[j];
            //j位置不知足條件時,循環跳出。因此t應該插入到j+1處。
            v[j+1]=t;
        }
    }
    return v;
}
//2. 二分法
vector<int> binarySort(vector<int> v)
{
    if(v.empty()) return v;
    int n=v.size()-1;

    for(int i=1;i<=n;i++)
    {
        if(v[i]<v[i-1])
        {
            int t=v[i];
            int left=0;
            int right=i-1;
            int mid=0;
            while(left>=0 && left<=right)
            {
                mid=(left+right)/2;
                //若是有2個以上的相同值,不能保證穩定排序
                if (v[mid]==t){ mid+=1; break;}
                else if(v[mid]<t) {left=mid+1;}
                else {right=mid-1;}
            }
            //mid處就是要插入的位置
            int j=i-1;
            for(;j>=mid;j--) v[j+1]=v[j];
            v[mid]=t; //v[j+1]=t;
        }
    }
    return v;
}

//測試
int main()
{
    int a[]={2,1,6,4,5};
    //int a[]={2,4,6,8,5};
    printVector(binarySort(vector<int>(a,a+5)));
}

References

相關文章
相關標籤/搜索