三种插入排序算法

2021-10-07  本文已影响0人  喜忧参半

直接插入排序

排序原理:
void insertsort(table *tab)
{
    int i,j;
    for(i=2;i<=tab->length;i++)
    {
        j=i-1;
        tab->r[0]=tab->r[i];
        while(tab->r[0].key<tab->r[j].key)
        {
            tab->r[j+1]=tab->r[j];
            j=j-1;
        }
        tab->r[j+1]=tab->r[0];
    }
}

关于时间复杂度

在最好情况下,直接插入排序算法的比较次数为n-1次,移动次数为2*(n-1)次。
在最坏情况下,直接插入排序算法的比较次数为(n+1)(n-1)/2次,移动次数为(n+2)(n-1)/2次。
在平均情况下,直接插入排序算法的时间复杂度为 O(n²)。另外该算法只使用了用于存放哨兵的一个附加空间。
直接插入排序算法是稳定的排序算法


二分法插入排序

排序原理
void binarysort(table *tab)
{
    int i,j,left,right,mid;
    for(i=2;i<=tab->length;i++)
    {
        tab->r[0]=tab->r[i];
        left=1,right=i-1;
        while(left<=right)
        {
            mid=(left+right)/2;
            if(tab->r[0].key<tab->r[mid].key)
                right=mid-1;
            else
                left=mid+1;
        }
        for(j=i-1;j>=left;j--)
            tab->r[j+1]=tab->r[j];
        tab->r[left]=tab->r[0];
    }
}

关于时间复杂度

对于二分法插入排序算法,在查找第i个记录的插入位置时,每执行一次while循环体,查找范围缩小一半,和直接插入排序的比较次数对比,二分法的比较次数少于直接插入排序的最多比较次数,而一般要多于直接插入排序的最少比较次数。
总体上讲,当n较大时,二分法插入排序的比较次数远少于直接插入排序的平均比较次数,但二者所要进行的移动次数相等,故二分法插入排序的时间复杂度也是O(n²),所需的附加存储空间为一个记录空间。
二分法插入排序算法是稳定的排序算法


Shell插入排序(希尔,缩小增量排序)

排序原理:
void shellsort(table *tab)
{
    int i,j,d;
    d=tab->length/2;
    while(d>=1)
    {
        for(i=d+1;i<=tab->length;i++)
        {
            tab->r[0]=tab->r[i];
            j=i-d;
            while(j>0&&tab->r[0].key<tab->r[j].key)
            {
                tab->r[j+d]=tab->r[j];
                j=j-d;
            }
            tab->r[j+d]=tab->r[0];
        }
        d=d/2;
    }
}

关于时间复杂度

shell排序中算法while循环的条件中j>0是为了保证比较时不会往左移超越哨兵元素而产生越界错误。
希尔排序一般而言比直接插入排序快,但要给出时间复杂度的分析相当难。至今为止也没有找到一个最好的缩小增量序列的选取方法。时间复杂度约为O(n^{(1.3-2)})
因此Shell插入排序算法是不稳定的排序算法

上一篇 下一篇

猜你喜欢

热点阅读