学习自左神
1,【转】科普:【坐在马桶上看算法】算法3:最常用的排序——快速排序
2,【经典快速排序】 -> 可以通过荷兰国旗问题优化-> 把数组分成3块区域,(小于+等于+大于) 区域
之前是2块区域,(小于等于 + 大于)区域
3,【随机快速排序】 目的是为了降低时间复杂度
经典快速排序 -> 默认选取数组最后一个数进行,数组切分。(与数据集有关系,最坏情况O(N平方))
随机快速排序 -> 通过随机选取L~R范围中的一个数,与最后一个数交换后,(属于概率事件,最后数学证明为O(N*logN))
【荷兰国旗代码思路】:
- 把数组分为3个区域,并且获得等于区域的下标
【荷兰国旗代码】
public class Code_08_NetherlandsFlag {
public static int[] partition(int[] arr, int l, int r, int p) {
int less = l - 1;
int more = r + 1;
while (l < more) {
if (arr[l] < p) {
swap(arr, ++less, l++);
} else if (arr[l] > p) {
swap(arr, --more, l);
} else {
l++;
}
}
return new int[] { less + 1, more - 1 };
}
【快排代码思路】
- 通过对数组最后一个数,进行划分(随机快排:随机取一个数与最后一个数进行交换,然后荷兰国旗问题)
- 通过获得数组等于区域下标,继续划分
【随机快排代码】:
public class QuickSort_01 {
// 1)主函数
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = { 4, 3, 5, 2, 6, 1, 2 };
quickSort(arr, 0, arr.length-1);
for (int i:arr) {
System.out.print(i + " ");
}
}
// 2) 普通快排函数调用,采用partition划分 -> 递归
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length-1);
}
public static void quickSort(int[] arr, int L, int R) {
if ( L < R) {
swap(arr, L+(int)(Math.random()*(R-L+1)), R);//随机快排就是加了这一行
int[] p = partition(arr, L, R);
quickSort(arr, 0, p[0]-1);
quickSort(arr, p[1]+1, R);
}
}
//3) Partiton 荷兰国旗问题 -> 找到等于区域下标
public static int[] partition(int[] arr, int L, int R) {
int less = L-1;
int more = R;
while (L < more) {
if (arr[L] < arr[R]) {
swap(arr, ++less, L++);
}else if (arr[L] > arr[R] ) {
swap(arr, --more, L);
}else {
L++;
}
}
swap(arr, more, R);
return new int[] { less+1, more};
}
// 交换函数
public static void swap(int[] arr, int i, int j) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}