快速排序:
思想:
1) 从数组中挑出一个基准值。
2) 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面,在这个分区退出之后,该基准就处于数列的中间位置。
3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。
经典算法实现:
package test;
import java.util.Arrays;
import java.util.List;
/**
* @author 欧阳
* @date 2022/3/7
*/
public class Demo05 {
public void quickSort(int[] A, int left, int right) {
if (left < right) {
int pivot = A[left];
int i = left;
int j = right;
while (i < j) {
while (i < right && A[i] <= pivot) i++;
while (j > left && A[j] >= pivot) j--;
if (i < j)
swap(A, i, j);
}
A[left] = A[j];
A[j] = pivot;
quickSort(A, left, j - 1);
quickSort(A, j + 1, right);
}
}
public void swap(int[] A, int i, int j) {
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
}
考虑极端情况:
如果是一个已经排好的数组, 挑选基准值时就应该取中间值
优化后:
import java.util.List;
/**
* @author 欧阳
* @date 2022/3/7
*/
public class Demo05 {
/**
* 快速排序(不稳定)
* @param people
* @param left
* @param right
*/
public void sort(People[] people, int left, int right) {
if (left < right) {
People pivot = selectPivot(people, left, right);
int i = left;
int j = right - 1;
while (i < j) {
while (i < j && people[++i].compareTo(pivot) < 0) ;
while (j > i && people[--j].compareTo(pivot) > 0) ;
if (i < j) {
swap(people, i, j);
} else {
break;
}
}
people[right - 1] = people[i];
people[i] = pivot; //将改值放置在其确定好的位置上,该值左边所有值比它小,右边所有值比它大
sort(people, left, i - 1);
sort(people, i + 1, right);
}
}
}
/**
* 选取中间值
*/
public People selectPivot(People[] people, int left, int right) {
int mid = (left + right) / 2;
People tmp;
if (people[left].compareTo(people[right]) > 0) {
tmp = people[right];
people[right] = people[left];
people[left] = tmp;
}
if (people[left].compareTo(people[mid]) > 0) {
tmp = people[left];
people[left] = people[mid];
people[mid] = tmp;
}
if (people[mid].compareTo(people[right]) > 0) {
tmp = people[right];
people[right] = people[mid];
people[mid] = tmp;
}
tmp = people[right - 1];
people[right - 1] = people[mid];
people[mid] = tmp;
return people[right - 1];
}
/**
* 交换传入数组中下标i的值和下标j的值
*/
public void swap(People[] people, int i, int j) {
People tmp = people[i];
people[i] = people[j];
people[j] = tmp;
}
package test;
/**
* @author 欧阳
* @date 2022/3/7
*/
public class People implements Comparable<People> {
private Integer age;
private String name;
public People() {
}
public People(Integer age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "People{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
/**
* 比较People年龄
*/
@Override
public int compareTo(People o) {
return Integer.compare(this.age, o.age);
}
}
快速排序是不稳定的算法,它不满足稳定算法的定义 算法稳定性--假设在数列中存在people[left] = people[right],若在排序之前,people[left]在people[right]前面;并且排序之后,people[leff]仍然在people[right]前面,则这个排序算法是稳定的! 快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*logN)。