一、算法设计与分析:
当输入设计已经几乎有序时,插入排序很快,而快速排序性能却不理想,所以当快速排序划分序列长度小于k时,改用插入排序能提高时间性能。即当序列长度大于等于k时用正常的快速排序,小于k时用插入排序。本实验尝试多个k值,以找出最佳k值,使得程序运行时间最佳。
二、算法实现
#include <iostream>
#define MAXSIZE 50000
#include <ctime>
#include <fstream>
using namespace std;
void print(int arr[], int start, int end);
void InsertSort(int arr[], int p, int r);
void exchange(int arr[], int i, int j);
void QUICKSORT(int arr[], int p, int r, int k);
int PARTION(int arr[], int p, int r);
void Sort(int arr[], int p, int r, int k);
int main(){
ofstream outfile;
int arr[MAXSIZE],arrSort[MAXSIZE];
int k;
clock_t start, finish;
outfile.open("D:\\data.txt");
for(int i=0;i<MAXSIZE;i++){
arr[i]=rand();
}
for(k=1;k<=500;k++){
for(int i=0;i<MAXSIZE;i++){
arrSort[i]=arr[i];
}
srand(time(0));
start=clock();
Sort(arrSort, 0, MAXSIZE-1, k);
finish=clock();
outfile << "k=" << k <<",time=" << finish-start<< endl;
}
printf("运行结束");
return 0;
}
void Sort(int arr[], int p, int r, int k) {
QUICKSORT(arr, p, r, k);
InsertSort(arr,p,r);
}
void InsertSort(int arr[], int p, int r){
int i,j;
int key;
for(j=p+1;j<=r;j++){
key=arr[j];
i=j-1;
while(i>=p && arr[i]>key){
arr[i+1]=arr[i];
i--;
}
arr[i+1]=key;
}
}
void QUICKSORT(int arr[], int p, int r, int k){
int q;
if(r-p+1>=k){
q=PARTION(arr,p,r);
QUICKSORT(arr,p,q-1,k);
QUICKSORT(arr,q+1,r,k);
}
}
int PARTION(int arr[], int p, int r){
int key;
int i,j;
i=p-1;
key=arr[r];
for(j=p;j<r;j++){
if(arr[j]<=key){
i++;
exchange(arr, i, j);
}
}
exchange(arr, i+1, r);
return i+1;
}
void exchange(int arr[], int i, int j){
int temp;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
void print(int arr[], int start, int end){
for(int i=start;i<=end;i++){
cout << arr[i] << ",";
}
cout << endl;
}
三、实验分析
观察实验结果可知,当实验数据为50000时,k=50左右,时间最优;当实验数据为100000时,k=83左右,时间最优。经过多组测试发现。当子序列较短时采用插入排序后时间效率比一直采用快速排序有明显提升。