排序算法之插入排序及C++实现

先声明:所有的排序我都会总结记录在博客里,最后会有一个大的cpp文件包含全部排序的代码,每个排序算法放在单独的一个namespace里面,清晰明了,并设计对数器给出测试。我会把它放到网盘供需要之人下载,见这里。 ps:所有的排序以升序为基准。测试编译器为Visual C++

插入排序思想:假设[0, i - 1]位置有序,将 i 位置元素插入到前面有序数组中适当的位置。一直到最后一趟,[0, n - 2]位置有序,将 n -1 位置元素插入进去即可。

插入排序:我们拆词,”插入“,如何理解”插入“这个词?理解了就简单了。

插入排序属于比较类的排序。

插入排序是稳定的。

最简单的demo:

template<typename T>
inline void swap(T* arr, size_t lhs, size_t rhs) {   // size_t是unsigned int的typedef
    T tmp(arr[lhs]);
    arr[lhs] = arr[rhs];
    arr[rhs] = tmp;
}
 
template<typename T>
void insertsort(T* arr, size_t size) {
    if (size <= 0)
        return;

    for (size_t i = 1; i < size; ++i) {
        for (size_t j = i; j >= 1; --j) {
            if (arr[j] < arr[j - 1]) {
                swap(arr, j, j - 1);
            }
        }
    }
}

上面这个是最简单的实现,有很多可以改进的地方。

假设 [0, i - 1]有序,现在需要把 i 位置元素插入到前面有序数组的适当位置;

  1. 上面代码是一直与前一个比较交换、比较交换,能不能先一直比较,直到找到正确位置,再最后交换一次即可呢?copy可是很费时的一个操作。

  2. [0, i - 1]有序呢,“有序”,能二分查找(binary search)?

上面都是可以实现的。

第1点的代码:

template<typename T>
void insertsort(T* arr, size_t size) {
    if (size <= 0)
        return;

    for (size_t i = 1; i < size; ++i) {
        T temp(arr[i]);
        size_t j = 0;
        for (j = i - 1; j >= 0; --j) {
            if (temp < arr[j]) {
                arr[j + 1] = arr[j];
            }
            else {
                break;
            }
        }
        arr[j + 1] = temp;
    }
}

第2点的代码:没贴出来,读者可以自己实现。二分查找的变种。

二分虽说简单,但是要写出来还是没那么容易的,《编程珠玑》书中作者谈到,在美国一所大学授课的时候,作者要求学生在纸上写出二分查找的代码,只要20%的人能够真正让作者满意,“纸上谈兵”可不是一个好事。

结果:
res
有个问题:这里我就用了这么简单一个例子,肯定说明不了这个算法是正确的。

可以设计对数器去判断,冒泡排序肯定是不会写错的,用随机生成的数组(元素随机,每个数组元素 个数也随机)去同时跑冒泡和待比较的排序算法,跑100000次,如果一次都没有出错,基本上可以证明待验证算法的正确性了。

平均时间复杂度 O(N^2)。
最好时间复杂度:正序,只需比较 N - 1 次,O(N)。
最差时间复杂度:逆序,O(N^2)。

空间复杂度都是 O(1)。

纸上得来终觉浅,绝知此事要躬行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值