排序【1】插入排序

常见排序

在实际生活中,排序的运用很多,排序就是将一组杂乱无章的数据升序或者降序排成有序的序列。常见的排序算法有。这里写图片描述
不同的排序算法适用于不同的场景下,衡量一个排序算法的标准不仅有空间复杂度,空间复杂度,还有稳定性。一个稳定的排序算法,相同的排序码在排序前后相对位置是不会发生变化的。
当然,排序也会根据数据量的情况,分为:
1.内部排序:数据可以加载到内存中进行排序。
2.外部排序:数据元素太多不能一次性加载到内存中,根据排序的情况不能再内存和外村中移动数据的排序。

插入排序

算法思想:每一步把一个元素key根据其排序码插入到它前面的一组已经排好序的序列中,直到所有元素排好序。
这里写图片描述
具体执行步骤:
(1)先认为第一个元素是已序的,第二个元素。
(2)去第二个元素,从后向前在已序的序列中比较。
(3)如果该元素比(已排序)比新元素大,将该元素移动到下一个位置。
(3)重复步骤三,直到找到比已排序元素小或者等于的元素。
(4)插入新元素到该位置。
(5)重复步骤(2)
算法性能
时间复杂度:
最优的情况下:就是数据元素已经是升序的,时间复杂度O(N);
最差的情况:数据序列是降序的,时间复杂度O(N^2);
空间复杂度:O(1)
稳定性:稳定。
适用的场景:当数据是已序的或者接近有序的,并且数据量比较小。
代码实现:

//最差的情况是降序拍,时间复杂度O(N^2)
//最好的情况是升序的,时间复杂度是O(N)
//平均时间复杂度O(N^2)
//稳定的排序算法。
//空间复杂度O(1)
void InsertSort(int *array,int size)
 {
    for (int i=1;i<size;i++)
    {
        int end = array[i];
        int j = i - 1;
        while (j >= 0 && array[j] > end)//找到带    c插入元素位置
        {
            array[j + 1] = array[j];
            j--;
        }
        array[j + 1] = end;

    }
}

我们可以用二分查找来提高查找插入位置的位置,来对插入排序进行优化,简称二分插入排序。
实现代码:

void BinaryInsertSort(int*array, int size)
{
    for (int i = 1; i < size; ++i)
    {
        int left = 0;
        int right = i - 1;
        int end = array[i];
        while (left<= right)    
        {
            int mid = left + ((right - left) >> 1);
            if (array[mid] < end)
            {
                left = mid + 1;
            }
            else
            {
                right = mid - 1;
            }

        }
        for (int j = i - 1; j >= left; --j)
        {
            array[j + 1] = array[j];
        }
        array[left] = end;


    }


}

希尔排序 (减增量排序)

从本质上来说,希尔排序是对直接插入排序的一种优化,为了避免直接插入排序出现最差的情况,希尔排序将数据元素进行了分组,先进行预排序,使数据逐渐接近有序,再使用插入排序。
基本思想:先将待排序序列分割成若干个子序列(子序列由相隔某个“增量”的元素组成),分别对这些子序列进行直接插入排序,然后减小“增量”,分组排序子序列,使序列 基本有序,最后再对全体元素进行一次直接插入排序。
这里写图片描述
适用场景:希尔排序是对插入排序的一种优化,当数据元素比较多时,适合希尔排序。
时间复杂度:当N比较大的时候,时间复杂度在O(N^1.25)-1.6O(N……1.25)之间
空间复杂度:O(1)
稳定性:不稳定
代码实现:

void ShellSort(int*array, int size)
{
    assert(array);
    int gap = 1;
    while (gap < size)
    {
        gap = gap * 2 + 1;
    }
    while (gap>=0)
    {
        for (int i = gap; i < size; ++i)
        {
            int key = array[i];
            int j = i - gap;
            while (j>0&&key<array[j])
            {
                array[j + 1] = array[j];
                j = j - gap;

            }
            array[j + gap] = key;
        }
        gap = gap / 3 + 1;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值