插入排序—折半插入排序

排序思路

和直接插入排序相似,先把待排序列看作连个部分:R[0……i-1]为有序,R[i……n-1]为无序。初始时,i=1,即有序部分为R[0]

和直接插入排序不同的是,无序元素向有序区插入的方式是通过折半查找到合适的位置。

在R[0……i-1]中(初始时low=0,high=i-1),采用折半查找方法得到R[i]的位置为R[high+1],然后将R[high+1,i-1]中的元素后移一个位置,最后将R[high+1]=R[i]

代码实现

#include <iostream>

using namespace std;

void insertSort(int a[],int n){
    int tmp,low,mid,high,j;
    //遍历无序区
    for(int i=1;i<n;i++){
        tmp=a[i];
        //low-high为有序区
        low=0;
        high=i-1;

        //二分查找,跳出hile循环时,high-i-1大于tmp,0-high-1左边小于tmp
        while(low<=high){
            mid=(low+high)/2;
            if(tmp<a[mid])
                high=mid-1;
            else
                low=mid+1;
        }
        //将high-(i-1)后移
        for(j=i-1;j>=high+1;j--){
            a[j+1]=a[j];
        }
        //将i插入到合适的位置
        a[high+1]=tmp;
    }

}
int main()
{
    int a[]={9,8,7,6,5,4,3,2,1,0};

    insertSort(a,10);
    for(int i=0;i<10;i++){
        cout << a[i] << endl;
    }
    return 0;
}

算法分析

因为如果待排序元素和有序区的元素相同,则R[high]=R[i],而最终R[i]元素的位置为R[high+1],所以折半插入排序是稳定的。

折半插入和直接插入的移动次数是相同的,都需要正确归位。折半查找平均关键字比较次数为log_{2}(i+1)-1,平均元素移动次

数为i/2+2平均时间复杂度为O(n^{2})。但就平均性能而言,折半插入优于直接插入。

猜你喜欢

转载自blog.csdn.net/SICAUliuy/article/details/88753650