算法导论——快排序算法及优化

一、算法设计与分析:

    当输入设计已经几乎有序时,插入排序很快,而快速排序性能却不理想,所以当快速排序划分序列长度小于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左右,时间最优。经过多组测试发现。当子序列较短时采用插入排序后时间效率比一直采用快速排序有明显提升。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值