快速排序及其优化

public class QuickSort {
	public static void main(String[] args) {
		int [] a ={1,2,3,0,9,8,7,6,5,4};
		Sort(a,10);
		for(int k=0;k<a.length ;k++){
			System.out.print(a[k]+"   ");
		}
	}
	private static void Sort(int[] k,int n) {
		QSort(k,0,n-1);
	}
	private static void QSort(int [] k,int low,int high) {
		int point;
		if(low<high){
			point =Partition(k,low,high);
			QSort(k,low,point-1);
			QSort(k,point+1,high);
		}
	}
	private static int Partition(int[] k,int low,int high) {
		int point;
		point=k[low];
		while(low<high){
			while(low<high&&k[high]>=point){
				high--;
			}
			swap(k,low,high);
			while(low<high&&k[low]<=point){
				low++;
			}
			swap(k,low,high);
		}

		return low;
	}
	private static void swap(int[] k, int low, int high) {
		int temp;
		temp=k[low];
		k[low]=k[high];
		k[high]=temp;
	}
}

优化一:优化选取基准点

取出数组中的头部,中间,尾部三个元素并比较大小,然后将三个值中最大的放到k[high],最小值放到k[middle],将中间值放到k[low],并设为point点。

private static int Partition(int[] k,int low,int high) {
		int point;
		int m=low+(high-low)/2;
		if(k[low]>k[high]){
			swap(k,low,high);
		}
		if(k[m]>k[high]){
			swap(k,m,high);
		}
		if(k[m]>k[low]){
			swap(k,m,low);
		}
		point=k[low];
		while(low<high){
			while(low<high&&k[high]>=point){
				high--;
			}
			swap(k,low,high);
			while(low<high&&k[low]<=point){
				low++;
			}
			swap(k,low,high);
		}

		return low;
	}

优化二:优化不必要的交换

这里有很多交换操作都是可以避免的。

private static int Partition(int[] k,int low,int high) {
		int point;
		int m=low+(high-low)/2;
		if(k[low]>k[high]){
			swap(k,low,high);
		}
		if(k[m]>k[high]){
			swap(k,m,high);
		}
		if(k[m]>k[low]){
			swap(k,m,low);
		}
		point=k[low];
		while(low<high){
			while(low<high&&k[high]>=point){
				high--;
			}
			//swap(k,low,high);
			k[low]=k[high];

			while(low<high&&k[low]<=point){
				low++;
			}
			//swap(k,low,high);
			k[high]=k[low];
		}
		k[low]=point;
		return low;
	}

优化三:优化小数组时的排序方案

在处理小于7个数的排序的时候,不必使用快速排序的方式了,这样效率会降低,使用直接插入排序的方式更优化。

private static void QSort(int [] k,int low,int high) {
		int point;
		if(high-low>7){
			point =Partition(k,low,high);
			QSort(k,low,point-1);
			QSort(k,point+1,high);
		}else{
			InsertSort(k,low,high);
		}
	}
	private static void InsertSort(int[] k, int low, int high) {
		int temp,j;
		for(int i=low;i<high;i++){
			if(k[i+1]<k[i]){
				temp=k[i+1];
				for( j=i;j>=low&&k[j]>temp;j--){
					k[j+1]=k[j];
				}
				k[j+1]=temp;

			}
		}
	}

如果是c语言的话还有优化四--递归的优化,利用尾调用可以进一步的让快速排序的速度更快。但是java不支持尾调用,这里就不详细介绍了。

下面是三个优化完成后的完整代码:

public class QuickSortImprove {
	public static void main(String[] args) {
		int [] a ={1,2,3,0,9,8,7,6,5,4};
		Sort(a,10);
		for(int k=0;k<a.length ;k++){
			System.out.print(a[k]+"   ");
		}
	}
	private static void Sort(int[] k,int n) {
		QSort(k,0,n-1);
	}
	private static void QSort(int [] k,int low,int high) {
		int point;
		if(high-low>7){
			point =Partition(k,low,high);
			QSort(k,low,point-1);
			QSort(k,point+1,high);
		}else{
			InsertSort(k,low,high);
		}
	}
	private static void InsertSort(int[] k, int low, int high) {
		int temp,j;
		for(int i=low;i<high;i++){
			if(k[i+1]<k[i]){
				temp=k[i+1];
				for( j=i;j>=low&&k[j]>temp;j--){
					k[j+1]=k[j];
				}
				k[j+1]=temp;
			}
		}
	}
	private static int Partition(int[] k,int low,int high) {
		int point;
		int m=low+(high-low)/2;
		if(k[low]>k[high]){
			swap(k,low,high);
		}
		if(k[m]>k[high]){
			swap(k,m,high);
		}
		if(k[m]>k[low]){
			swap(k,m,low);
		}
		point=k[low];
		while(low<high){
			while(low<high&&k[high]>=point){
				high--;
			}
			k[low]=k[high];
			while(low<high&&k[low]<=point){
				low++;
			}
			k[high]=k[low];
		}
		k[low]=point;
		return low;
	}
	private static void swap(int[] k, int low, int high) {
		int temp;
		temp=k[low];
		k[low]=k[high];
		k[high]=temp;
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-04 16:42:45

快速排序及其优化的相关文章

快速排序的优化(一)随机化快速排序

这周研究快速排序优化策略,首先是利用随机化对快速排序进行优化. 众所周知,之前的基础快速排序算法,其效率一个关键点就在与划分元素的选取,由于之前一直选取的是第一个元素,所以当遇到特殊输入,比如太大或者太小,就会造成区间划分极度不合理. 引入随机化,就是在每一次划分的时候随机选取一个元素作为关键字,用它来进行划分.由于每一次划分都是随机选取,所以每一次都选到不好的元素概率低,可以作为一个优化的方向. 和之前的基础快速排序主要区别有两个 1.首先是partition部分 利用rand产生随机数  ,

温故知新,基础复习(快速排序及优化)

温故知新,基础复习(快速排序及优化) 使用了三值取中和插排优化 #include<stdio.h> #define InsertSortNumber 10 void InsertSort(int Arra[],unsigned int LowIndex,unsigned int HighIndex) { printf("low=%d,high=%d\n",LowIndex,HighIndex); for (unsigned int i = LowIndex + 1; i &

算法整理(四):浅析快速排序的优化问题

前文介绍了快速排序的单边扫描和双边扫描,但么有做对比,今天来简单分析下. 一.单边扫描的缺点 单边扫描最大的缺点是每次都要交换,如果一个数组是 5 4 3 2 1,用单边扫描的话,则从4开始,4要和4交换一次,3要和3交换一次,依次类推,这种无意义的操作.正因此用双边扫描会更好,第一趟只需交换一次,就能得到1 4 3 2 5这样的数组.但双边扫描也是可以进一步优化的. 二.双边扫描的优化 优化一:对key值得选取应该使用随机选取的原则,而非第一个数字.意义大家都懂得. 优化二:前文的方法是挖坑法

快速排序及优化(Java实现)

普通快速排序 找一个基准值base,然后一趟排序后让base左边的数都小于base,base右边的数都大于等于base.再分为两个子数组的排序.如此递归下去. public class QuickSort { public static <T extends Comparable<? super T>> void sort(T[] arr) { sort(arr, 0, arr.length - 1); } public static <T extends Comparabl

【决战西二旗】|快速排序的优化

1.前言 前面的一篇文章https://www.cnblogs.com/backnullptr/p/11934841.html讲了快速排序的基本概念.核心思想.基础版本代码实现等,让我们对快速排序有了一个充分的认识,但还无法达到面试中对快速排序灵活应对的程度. 快速排序是图领奖得主发明的算法,被誉为20世纪最重要的十大算法之一,快速排序为了可以在多种数据集都有出色的表现,进行了非常多的优化,因此对我们来说要深入理解一种算法的最有效的手段就是不断优化提高性能. 通过本文你将了解到以下内容: 快速排

三种快速排序以及快速排序的优化

一.  快速排序的基本思想 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 二.  快速排序的三个步骤 1) 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot): 2) 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列.此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大: 3) 递归地对两个序列进行快速排序,直到

快速排序及优化(Java版)

快速排序(Quicksort)是对冒泡排序的一种改进.快速排序由C. A. R. Hoare在1962年提出. 一次快速排序详细过程: 选择数组第一个值作为枢轴值. 代码实现: package QuickSort; public class QuickSortRealize { public static void QuickSort(int[] arr){ QSort(arr,0,arr.length-1); } //对顺序表子序列作快速排序 待排序序列的最小下标值low和最大下标值high

【转】三种快速排序算法以及快速排序的优化

一.  快速排序的基本思想 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 二.  快速排序的三个步骤 1) 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 “基准”(pivot): 2) 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列.此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大: 3) 递归地对两个序列进行快速排序,直到序列为空或

排序算法杂谈(五) —— 关于快速排序的优化策略分析

1. 前提 排序算法(六) -- 归并排序 排序算法(七) -- 快速排序 排序算法杂谈(四) -- 快速排序的非递归实现 2. 优化策略1:主元(Pivot)的选取 归并排序(Merge Sort)有一个很大的优势,就是每一次的递归都能够将数组平均二分,从而大大减少了总递归的次数. 而快速排序(Quick Sort)在这一点上就做的很不好. 快速排序是通过选择一个主元,将整个数组划分(Partition)成两个部分,小于等于主元 and 大于等于主元. 这个过程对于数组的划分完全就是随机的,俗