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