快速排序优化(待完善)——C语言

本文探讨了一种结合快速排序和插入排序的优化算法,当子数组接近有序时,利用插入排序的高效性,通过设定阈值k,对小规模子数组跳过快速排序直接进行插入排序,以提升整体排序效率。

 


当输入数据已经“几乎有序”时,插入排序速度很快。在实际应用中,我们可以利用这一特点来提高快速排序的速度。当对一个长度小于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;
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值