论插入排序用二分查找优化后,到底能快多少?(C语言测试)

插入排序的代码:(优势在于这种从后往前扫描可以边扫描边把大的往后挪。。)

int* sortArray(int* nums, int numsSize, int* returnSize){
    *returnSize=numsSize;
    int i = 1;
    while(i<numsSize){
        int temp = nums[i];//为需要插入排序的对象创建临时副本,以便从后向前扫描将元素后移腾出位置
        int j = i - 1;
        //从后往前比较(扫描元素),若比该插入对象大则后移(顺序存储的元素插入的必经操作)
        while(j>=0&&nums[j]>temp){
            nums[j+1] = nums[j];
            j--;
        }
        //经过扫描后,找到位置应为j+1
        nums[j+1] = temp;
        i++;
}return nums;
}

二分查找优化后的代码:(可惜不能边扫描边挪位)


int* sortArray(int* nums, int numsSize, int* returnSize){
    *returnSize=numsSize;//这是leetcode上需要告知返回多少数据的数组,大家可以忽略
    /*每个nums[i]就是需要进行插入的对象,由于是先二分查找,
    则需要前面的数据是有序的,所以应该从前面只有一个元素时开始插入,
    这样便可以确保每次插入时,前面的元素都是有序的。*/
    int i = 1,temp,l,r,mid;
    while(i<numsSize){
        temp = nums[i];
        l = 0;
        r = i-1;
        while(l<=r){
            mid = (l + r) / 2;
            if(temp<nums[mid])
                r = mid - 1;
            else if(temp>nums[mid])
                l = mid + 1;
            else{
                l = mid + 1;
                break;
            }   
        }
/*虽说二分查找大大降低了查找的时间,
但是却避免不了数组的插入操作需要把所有元素往后移动,才能插入
这也就导致时间复杂度不是O(NlongN)而是O(n^2)
但仍然比原本的插入查找要快一点(数据多的时候可体现)*/
        for(int j=i-1;j>=l;j--)
            nums[j+1] = nums[j];
        nums[l] = temp;
        i++;
}return nums;
}

下面就是通过实验对该优化方案进行实际评断了,由于优化以便都是体现在大量数据上,所以先是尝试了10w数据结果两者都以超时结束。。

1.关于优化后是否能跑动更多的数据:
答案是没有,很显然时间复杂度仍然时O(n^2),经过我的测试无论是优化前还是优化后,当我以十万个数据为样本进行排序时,都是会超时的(实测大概需要5000ms)。我获得样本的方式是通过rand()函数进行创建的,然后利用word文档对这些数据进行格式化,放入leetcode912题进行测试用例,进行测试。在这里插入图片描述
妥妥的10w个数据
在这里插入图片描述

2.通过二分查找优化后具体大概快多少?
我这次就学乖了,只用了1w的测试用例,分别测试了优化前和优化后。(分别测试5次,误差大的数据不要)
优化前:
第一次:96ms。第二次:124ms。第三次:148ms
第四次:120ms。第五次:144ms。
平均数为:126.4ms
优化后:
第一次:88ms。第二次:96ms。第三次:100ms
第四次:80ms。第五次:108ms。
平均数为:94.4ms
所以我们看得出优化后的代码虽然是跑的快了那么一点点。。。可是仍然无足轻重啊。。。
3.这次实验的收获:
以后做题时大家切记,如果你写的一个代码超时了,那么无论你如何优化,只要时间复杂的量级仍然没有改变,那么毫无疑问,优化后这个代码也是于事无补的。。。所以…无脑快排吧。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值