快速排序及其优化
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;
}
}