快速排序
什么是快速排序
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,比另一部分的关键字大,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
- 时间复杂度:O(nlgn)
- 空间复杂度:O(1)
- 稳定性:不稳定
图解快速排序
单路快速排序代码
public void sort(int[] arr) {
quickSort(0, arr.length - 1);
}
private void quickSort(int L, int R) {
if (L >= R) {
return;
}
//先对数组进行划分 并返回划分后的中点
int p = partition(L, R);
quickSort(L,p - 1);
quickSort(p + 1, R);
}
private int partition(int L, int R) {
//优化一下 随机让后面的数字和第一个数字换一下
//尽量避免极端情况
swap(L, (int) (Math.random() * (R - L + 1) + L));
int v = arr[L];
//arr[l+1 ~ j] < v < arr[j+1 ~ i)
int j = L;
for (int i = L + 1; i <= R; i++) {
if (arr[i] < v) {
swap(j + 1, i);
j++;
}
}
swap(L, j);
return j;
}
public void swap(int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
双路快速排序代码
public void sort(int[] arr) {
quickSort(0, arr.length - 1);
}
private void quickSort(int L, int R) {
if (L >= R){
return;
}
//先对数组进行划分 并返回划分后的中点
int p = partition(L, R);
quickSort(L, p - 1);
quickSort(p + 1, R);
}
private int partition(int L, int R){
swap(L, (int)(Math.random() * (R - L + 1) + L));
int v = arr[L];
int i = L + 1;
int j = R;
while (true){
while (i <= R && arr[i] < v){
i++;
}
while (j >= L + 1 && arr[j] > v){
j--;
}
if (i > j){
break;
}
swap(i,j);
i++;
j--;
}
swap(L,j);
return j;
}
public void swap(int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
三路快速排序代码
public void sort(int[] arr) {
quickSort(0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private void quickSort(int L, int R) {
if (L >= R){
return;
}
swap(L, (int)(Math.random() * (R - L + 1)) + L);
int v = arr[L];
int lt = L;
int gt = R + 1;
int i = L + 1;
while (i < gt){
if (arr[i] < v) {
swap(i, lt + 1);
lt++;
i++;
}else if (arr[i] > v){
swap(i, gt - 1);
gt--;
}else {
i++;
}
}
swap(L,lt);
quickSort(L,lt - 1);
quickSort(gt, R);
}
public void swap(int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}