排序之-----插入排序于希尔排序

插入排序

插入排序基本思想:每一步将一个元素的排序码按照大小,插入到前面已经排好序的元素之中的合适位置,直到最后一个元素也插入了他之前的有序序列。

直接插入排序 将array[i] 插到已经有序的array[0] array[i] ….. array[i - 1]中 先保存array[i]一个个比较 找到了位置后 将其他数均向后移动一个位置。 最后插入保存好的元素。

直接插入排序在对待待排序列基本有序且规模不大时 比较好
时间复杂度在O(n) 与O(n ^ 2)之间 一般认为是O(n ^ 2)。 空间复杂度O(1)。

图示:
这里写图片描述

//直接插入排序   写代码关键在于理解end的位置
template<class T>
void InsertSort(T* arr, size_t n)
{
    assert(arr && n > 0);
    size_t front = 0;

    for (; front < n - 1; ++front){
        int end = front;            //有序数列的最后一个是end
        T tmp = arr[end + 1];
        while (end >= 0){
            if (arr[end] > tmp){//比要插入的数字大就向后移
                arr[end + 1] = arr[end];
                --end;
            }
            else
                break;
        }    //必要插入的数字小就让它插在后面
        arr[end +`
1] = tmp;
    }
}

希尔排序

设待排序元素有n个,首先取一个整数gap < n作为间隔,将全部元素分为gap组,所有距离为gap的元素都在同一个组里,然后对每一个组都进行插入排序。然后缩小增量,直到gap==1的时候整个序列都会变成有序的。希尔排序是直接插入排序的变形。

图示:
这里写图片描述

代码:

template<class T>
void ShellSort(T* arr, size_t n)
{
    assert(arr);
    int gap = n;
    while (gap > 1){
        gap = gap / 3 + 1;
        for (int front = 0; front < n - gap; front++){
            int end = front;
            T tmp = arr[end + gap];
            while (end >= 0){
                if (arr[end] > tmp){
                    arr[end + gap] = arr[end];
                    end -= gap;
                }
                else{
                    break;
                }
            }
            arr[end + gap] = tmp;
        }
    }
}

进行希尔排序的时候gap的选取很重要,决定了排序效率的高低,一般最开始设置gap为要排序的元素的个数,接下来gap按照gap=gap/3+1的趋势进行变化。希尔排序的平均时间复杂度是在n^1.25到1.6n^1.25的范围内。

希尔排序与插入排序的比较:
插入排序在什么情况下效率最高呢???

如果当要排序的序列大致上接近于有序的时候,插入排序的效率最高,基本上接近O(N)。因为当数据基本上接近于有序的时候,元素向有序区插入的时候比较的次数会很少,同样有序区元素向后移动的次数也是很少的。

####那么插入排序在什么情况下的效率最低呢???
如果当要排序的序列大致上接近于逆序的时候,插入排序的效率最低,基本上接近与O(N*N)。因为这时候每向有序区插入一个元素的时候,假设最极端的情况下要比较和移动的次数就是有序区的长度。这时候插入排序的效率就会很低。

针对于插入排序的最坏的情况,希尔排序对它进行了优化,希尔排序先对这组数据进行预排序(就是gap不为1的时候进行的分组排序),通过预排序就能将这组数据快速的接近于有序,这时候再使用插入排序效率就会提升上去。所以希尔排序的增量选择就很重要,增量大额话会起不到预排序的效果,增量小的话效率又会降低。

如果当一组数据接近的有序的话,我们优先使用插入排序,效率高。如果当一组数据接近于逆序的话,我们使用希尔排序会更优。插入情况最好的情况就是希尔排序最坏的情况,因为这时候希尔排序的预排序起不到作用。插入排序最坏的情况则是希尔排序最高的情况,因为这时候预排序的效果是非常明显的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值