内部排序(1)——插入类排序

#插入类排序 ##一、直接插入排序

算法分析: 从空间角度来看,只需要一个辅助空间r[0]。 从时间角度来看,主要时间耗费在关键字比较和移动元素上。 直接插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。 直接插入排序是稳定的。 **直接插入排序在基本有序时效率较高,并且在序列规模不是很大时效率也很高。**

void InsertSort(int a[],int len)    //直接插入排序 
{
    int i = 1;
    int j = 0;

    for(i = 2; i <= len; ++i)
    {
        a[0] = a[i];
        for(j = i-1; j > 0 && a[j] > a[0]; j--)
        {
            a[j+1] = a[j];
        }
        a[j+1] = a[0];
    }
}

二、二分插入排序

算法分析: 采用折半插入排序法,可减少关键字的比较次数。每插入一个元素,需要比较的次数最大为折半判定树的深度。**虽然折半插入排序法与直接插入排序法相比较,改善了算法中比较次数的数量级为O(nlog2n),但其并未改变移动元素的时间耗费,所以折半插入排序总的时间复杂度仍然是O(n^2)。**

void BinInsertSort(int a[],int len) //二分插入排序 
{
    int i = 0;

    for(i = 2; i <= len; ++i)
    {
        int low = 1;
        int high = i-1;
        int mid = 0;
        a[0] = a[i];
        while(high >= low)
        {
            mid = (low + high)/2;
            if(a[0] <= a[mid]) 
            {
                high = mid - 1;
            }
            else  //把等于划到这一类可以在有多个相同值时减少相同值移动的次数;
            {
                low = mid + 1;
            }
        }
        int tmp = 0;
        for(int j = i - 1; j >= low; j--)
        {
            a[j+1] =  a[j];
            tmp++;
        } 
        cout<<endl<<i<<"移动%d次:"<<tmp<<endl; 
        a[low] = a[0];
    }

} 

上述代码中的逻辑设计的实际区别如下:

(1)把等于划到下面
这里写图片描述
(2)把等于划到上面

可见,把等于号放在下面的分支,相当于遇到相等元素时、不在进行比较能够提高效率。

三、shell排序

算法分析:shell排序是对直接插入排序的一种改进(从后续的代码中可以看出),延续了直接插入排序的优点,核心思想是: >待排序列有n个元素,先取一个小于n的整数h1作为第一个增量,把待排序列以间隔h1分成若干子序列,子序列内使用插入排序; >然后取第二个增量h2(

void ShellSort(int a[], int len , int d[], int dlen)//shell排序非递归实现 
{
    int i = 0,j = 0,n = 0;
    for(i = 0;i<dlen; ++i)     //共有dlen种偏移因子 
    {
        for(n = 1; n < d[i]+1; n++)   //共有d[i]组 
        {
            for(j = n+d[i]; j<=len; j +=d[i])  //一组插入 
            {
                a[0] = a[j];
                int k = j-d[i];
                while(k>0 &&  a[k] > a[0])
                {
                    a[k+d[i]] = a[k];
                    k = k-d[i]; 
                }
                a[k+d[i]] = a[0];
            }

        }
    }
} 

总结:

插入排序时间复杂度稳定性
直接插入排序O(n^2)稳定
二分插入排序比较O(nlog2n)、移动O(n^2)稳定
shell排序O(n^1.5)不稳定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值