快速排序又叫快排、思路是找一个元素作为pivot、我们选取最后的元素作为pivot、从数组首位开始遍历、将小于pivot的放在数组前面的位置、最后将pivot放在两个分区的中间、pivot的右边的元素都大于pivot、左边的元素都小于pivot、这就分好了两个区域、然后继续对两个区域分区–>指定pivot、交换元素、分区…直到分区只有一个元素的时候也就都有序了。
时间复杂度为log2n、但是最坏的情况下也会变为O(n²):假设数组是有序的、那么每次找的pivot都是数组中最大的元素、那么每次都要将数组遍历完、时间复杂度就会变成O(n²)、那么我们可以对此做出优化、每次取pivot的时候、找出三个数、找出三个数中间的数作为pivot、也可以随机数选取pivot来分区。
三向切分法优化、假设数组中的重复的元素比较多的话:我们假设第一次选取的pivot在数组中存在多个重复的、那么将与pivot相同的元素都排在了pivot的前面、pivot之前的元素已经是有序的了、那么就没有必要继续对pivot之前的元素继续分区了。那么我们可以做出优化、将数组分为三个区域、小于pivot 的区域、等于pivot的区域、大于pivot的区域、下次分区的时候只分小于pivot的、和大于pivot的区域即可。
原始的写法
class Sort {
public static void main(String[] args) {
int[] array = {23, 434, 577, 8, 9, 91, 6, 2, 1};
quickSort(array);
System.out.println(Arrays.toString(array));
;
}
public static void quickSort(int[] array) {
sort(array, 0, array.length - 1);
}
public static void sort(int[] array, int low, int high) {
if (low >= high) {
return;
}
int par = partition(array, low, high);
sort(array, low, par - 1);
sort(array, par + 1, high);
}
public static int partition(int[] array, int low, int high) {
int pivot = array[high];
int less = low;
int great = low;
for (; great < high; great++) {
if (array[great] < pivot) {
int tmp = array[less];
array[less] = array[great];
array[great] = tmp;
less++;
}
}
int tmp = array[high];
array[high] = array[less];
array[less] = tmp;
return less;
}
}
随机数法优化
public static void swap(int[] array, int index1, int index2) {
int tmp = array[index1];
array[index1] = array[index2];
array[index2] = tmp;
}
public static void quickSort(int[] array) {
sort(array, 0, array.length - 1);
}
public static void sort(int[] array, int low, int high) {
if (low >= high) {
return;
}
int par = partition(array, low, high);
sort(array, low, par - 1);
sort(array, par + 1, high);
}
public static int getPivotIndex(int[] array, int low, int high) {
return new Random().nextInt(high - low) + low;
}
public static int partition(int[] array, int low, int high) {
//随机数法:
int index = getPivotIndex(array,low,high);
//将随机数与最右边的元素交换、也就是之前的排序
swap(array,high,index);
int pivot = array[high];
int less = low;
int great = low;
for (; great < high; great++) {
if (array[great] < pivot) {
swap(array,less,great);
less++;
}
}
swap(array,less,high);
return less;
}
三向切分法优化
class ThreeWaySort{
public static void main(String[] args) {
int[] array = {34,42,2,133,766,64,43};
quicksort(array);
System.out.println(Arrays.toString(array));
}
public static void quicksort(int[] array){
sort(array,0,array.length-1);
}
public static void sort(int[] array,int low,int high){
if (low >= high){
return;
}
int pivot = array[high];
int less = low;
int great = high;
int i = low;
while (i <= great){
if (array[i] < pivot){
swap(array,i,less);
less++;
i++;
} else if (array[i] > pivot){
swap(array,i,great);
great--;
i++;
} else {
i++;
}
}
sort(array,low,less-1);
sort(array,great+1,high);
}
public static void swap(int [] array,int index1,int index2){
int tmp = array[index1];
array[index1] = array[index2];
array[index2] = tmp;
}
}