课后题里面有这么一道题。
2.3-6.在插入排序法中,对已排序的子数组反向扫描。是否可以采用2分查找策略。将插入排序的总体最坏运行时间改善为O(nlgn)? 以下是代码实现部分。
#include <iostream>
#include <time.h>
#include<stdlib.h>
using namespace std;
void main()
{
const int n=10;
int a[n],key,med;
srand( (unsigned)time( NULL ) );
for(int i=0;i<n;i++)
{
a[i]=rand()%101;
}
cout<<"排序前:"<<endl;
for ( i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
for (int j=2;j<=n;j++)
{
key=a[j-1];
int end=j-2,beg=0;
while(beg<=end)
{
med=(end+beg)/2;
if (a[med]>key)
{
end=med-1;
}
else if (a[med]<=key)
{
beg=med+1;
}
}
for (int i=j-2;i>=med;i--)
{
if (key>a[i])//要插入的key值大于a[i](带插入的有序数列)中的第i个值后,跳出循环。
{
med=i+1;//所以key值必小于等于a[i+1],将a[i+1]的下标赋值给待插入的元素的下标。
break;
}
a[i+1]=a[i];
}
a[med]=key;//上面的循环保证了下标为med的数组元素正好插入到了正确位置。
}
//这个算法的时间复杂度为:nlgn+n^2 不能改善为nlgn,采用链表的数据结构就不需要数组插入时的数据移动n^2,则可以改善。
cout<<"排序后:"<<endl;
for ( i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;