快速排序及其优化
package com.zc.algorithm;
public class QuickSort {
//快速排序:挖坑法
public int partition(int[] arr, int left, int right)
{
if(left<right)
{
int temp = arr[left];
while(left<right)
{
//如果右边的数大于基数temp,则向左移动
while(left<right&&arr[right] >= temp)
{
right--;
}
//如果不大于,则把右边的数赋值给左边
arr[left] = arr[right];
//如果左边的数小于基数,则向右移动
while(left<right&&arr[left] <= temp)
{
left++;
}
//如果左边的数大于基数,则左边的数赋值给右边
arr[right] = arr[left];
}
arr[left]=temp;
}
return left;
}
public int[] QSort(int[] arr, int left, int right)
{
int[] newArr = arr;
if(left < right)
{
int pivot = partition(newArr, left, right);
QSort(newArr,left,pivot-1);
QSort(newArr, pivot+1,right);
}
return newArr;
}
//快速排序优化1:三数取中法,将数组中的开头、结尾和中间的数做比较,把最大的放在末尾,然后把最小的放在中间,第二大的放在开头,解决数组中部分有序的问题
public void MedianOfThree(int[] arr, int left, int right)
{
int mid = left+(left+right);
if(arr[left] > arr[right])//把最大值放在数组的末尾
{
swap(arr, left, right);
}
if(arr[mid]> arr[right])//把最大值放在数组的末尾
{
swap(arr, mid, right);
}
if(arr[mid]>arr[left])//把最小值放在中间
{
swap(arr, mid, left);
}
}
//交换
public void swap(int[] arr, int left, int right)
{
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
public int[] QSort_MedianOfThree(int[] arr, int left, int right)
{
//[1]先进行数字调换
MedianOfThree(arr,left,right);//将中间数放到开头
int[] newArr = arr;
if(left < right)
{
int pivot = partition(newArr, left,right);
QSort(newArr,left,pivot-1);
QSort(newArr, pivot+1,right);
}
return newArr;
}
//快速排序优化2:三数取中+插入排序
public int[] insertSort(int[] arr)
{
int j = 0;
for(int i = 1; i< arr.length; i++)
{
int temp = arr[i];
for( j = i-1; j >=0&&arr[j]>temp;j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
return arr;
}
public int[] QSort_Insert(int[] arr, int left, int right)
{
//如果数组的长度小于10,则采用插入排序
if(right - left +1 < 10)
{
return insertSort(arr);
}
//[1]先进行数字调换
MedianOfThree(arr,left,right);//将中间数放到开头
int[] newArr = arr;
if(left < right)
{
int pivot = partition(newArr, left,right);
QSort(newArr,left,pivot-1);
QSort(newArr, pivot+1,right);
}
return newArr;
}
//快速排序优化3:三数取中+插排+聚集相同元素,解决数组中部分重复的问题
public int[] QsortThreeInsertGather(int[] arr, int low, int high)
{
if(high - low+1<10)
{
return insertSort(arr);
}
//三数取中
MedianOfThree(arr, low, high);
int first = low;
int last = high;
int left = low;
int right = high;
int leftLength = 0;
int rightLength = 0;
int key = arr[first];
while(first < last)
{
while(first < last&&arr[last]>=key)
{
if(arr[last] == key)
{
swap(arr, last, right);
right--;
rightLength++;
}
last--;
}
arr[first] = arr[last];
while(first<last&& arr[first]<=key)
{
if(arr[first] == key)
{
swap(arr, first,left);
left++;
leftLength++;
}
first++;
}
arr[first] = key;
}
int i = first - 1;
int j =low;
while(j < left&&arr[i]!=key)
{
swap(arr,i,j);
i--;
j++;
}
i =last+1;
j = high;
while(j>right&&arr[i]!=key)
{
swap(arr,i,j);
i++;
j--;
}
QsortThreeInsertGather(arr,low,first-leftLength-1);
QsortThreeInsertGather(arr,first+rightLength+1,high);
return arr;
}
}