当输入数据已经“几乎有序”时,插入排序速度很快。在实际应用中,我们可以利用这一特点来提高快速排序的速度。当对一个长度小于k的子数组调用快速排序时,让它不做任何排序就返回。当上层的快速排序调用返回后,对整个数组运行插入排序来完成排序过程。试证明:这一排序算法的期望时间复杂度为O(nk+nlg(n/k))。分别从理论和实践的角度说明我们应该如何选择k?
此处实现的k值为手动输入,主观选择的。还没有做到合理选择k值。
待修改:根据运行时间选择k值。
/*
*File name:Quicksort
*Author:Fei Yuling Version:2.0 Date:2018.10.31
*Description:快速排序的优化,当子数组长度小于k时,什么都不做,直到上层递归完后全数组进行插入排序
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX 20
/*
*函数名:print
*作用:打印数组
*参数:len-数组长度,arr-数组
*返回值:无
*/
void print(int len,int arr[])
{
if(len>0)
{
int i;
for(i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
else if(len=0) printf("数组为空\n");
else printf("数组错误\n");
}
/********************************
*函数名:swap
*作用:交换两个数的值
*参数:*a,*b-要交换的两个数
*返回值:无
********************************/
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
/*
*函数名:quicksort
*作用:快速排序
*参数:arr-待排数组,begin-划分的开头,end-划分的结尾,k-快排优化的参数,当子数组长度小于k时什么都不做
*返回值:
*/
void quicksort(int arr[], int begin, int end,int k)
{
int i,j,m;
m=end-begin+1;
if(m<=k)
{
return;
}
if(begin<end)
{
i=begin+1;//每划分后第一个数字为基准,从基准后一个数字作为开头
j=end;//最后一个数字为结尾
while(i<j)//当i=j时跳出循环
{
if(arr[i]>arr[begin]) //从开头依次与基准比较,比基准大就与j交换
{
swap(&arr[i],&arr[j]);
j--;//交换后j前移
}
else
{
i++;//否则i后移
}
}
/*此时i=j*/
if(arr[i] >= arr[begin]) //当最终停留的数字大于等于基准时,i前移,即此数在枢纽之后
{
i--;
}
swap(&arr[begin], &arr[i]);//将基准放在枢纽位置
quicksort(arr,begin,i,k);//递归
quicksort(arr,j,end,k);
}
}
/*
*函数名:insertsort
*作用:插入排序
*参数:arr-待排数组,n-数组总长度
*返回值:
*/
void insertsort(int arr[],int n)
{
int i,j,key;
for(j=1;j<n;j++)
{
i=j-1;
key=arr[j];
while(i>=0&&arr[i]>key)//待排的那个数字从它前面的数字开始依次往前比较,如果比待排数字大就往后挪
{
arr[i+1]=arr[i];
i--;
}
arr[i+1]=key;//退出循环时i-1了,所以此时待排数字要放在a[i+1]的位置上
}
}
int main()
{
int n,i,k;
int arr[MAX];
printf("请输入待排序列数字个数(不超过%d个):",MAX);
scanf("%d",&n);
if(n<0||n>MAX)
{
printf("输入值错误!");
return 0;
}
printf("请输入待排序列:");
for(i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
printf("请输入快速排序优化的参数k:");
scanf("%d",&k);
if(k<=0||k>=n)
{
printf("k的取值错误!");
return 0;
}
quicksort(arr,0,n-1,k);
printf("快速排序后的数组为:\n");
print(n,arr);
insertsort(arr,n);
printf("插入排序后的数组为:\n");
print(n,arr);
return 0;
}