快速排序比起冒泡排序一般要快上许多,他的思想是将要排序的数据不断切割,分而治之。
下面是基本的快速排序写法:
public static void quickSort1(int[] arr, int i, int j){
int start = i;
int end = j;
int temp = arr[i];
while (i < j){
while (i < j && temp < arr[j]){
--j;
}
while (i < j && arr[i] < temp){
++i;
}
if (i < j && arr[i] == arr[j]){
++i;
} else {
int temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
if (start < i){
quickSort1(arr, start, i - 1);
}
if (j < end){
quickSort1(arr, j + 1, end);
}
}
它将最左边的数作为基准,分别将大于它和小于等于它的数放在两边切割排序。
它的时间复杂度是在n*logn和n平方之间,当数据已排序,每次指挥切割一个数据,时间复杂度为n平方,所以我们可以用随机数来设置基准
public static void quickSort2(int[] arr, int i, int j){
int start = i;
int end = j;
int random = new Random().nextInt(j - i + 1) + i;
int temp = arr[random];
while (i < j){
while (i < j && temp < arr[j]){
--j;
}
while (i < j && arr[i] < temp){
++i;
}
if (i < j && arr[i] == arr[j]){
++i;
} else {
int temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
if (start < i){
quickSort2(arr, start, i - 1);
}
if (j < end){
quickSort2(arr, j + 1, end);
}
}
但是随机数并不能有效解决这个问题,于是就来了三数(最左、中间、最右)取中设置基准,让最左边的数为三个数的中间值
public static void quickSort3(int[] arr, int i, int j){
int start = i;
int end = j;
int mid = (i + j) >> 1;
if (arr[start] < arr[mid]) {
swap(arr, start, mid);
}
if (arr[end] < arr[mid]) {
swap(arr, end, mid);
}
if (arr[start] > arr[end]) {
swap(arr, start, end);
}
int temp = arr[start];
while (i < j){
while (i < j && temp < arr[j]){
--j;
}
while (i < j && arr[i] < temp){
++i;
}
if (i < j && arr[i] == arr[j]){
++i;
} else {
int temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
if (start < i){
quickSort3(arr, start, i - 1);
}
if (j < end){
quickSort3(arr, j + 1, end);
}
}
前面都是每次两两划分数据,将等于基准的数归到了小于的数据一起划分,其实这就是多余的部分,我们可以将等于基准的数据放在一起,减少划分次数,于是三路划分的快排就来了
public static void quickSort4(int[] arr, int i, int j){
int start = i;
int end = j;
int mid = (i + j) >> 1;
if (arr[start] < arr[mid]) {
swap(arr, start, mid);
}
if (arr[end] < arr[mid]) {
swap(arr, end, mid);
}
if (arr[start] > arr[end]) {
swap(arr, start, end);
}
int temp = arr[start];
while (i < j){
while (i < j && temp < arr[j]){
--j;
}
while (i < j && arr[i] < temp){
++i;
}
if (i < j && arr[i] == arr[j]){
++i;
} else {
int temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
int count1 = 1;
int count2 = 1;
ok:for (int k = start; k < i - count1; k++) {
if (arr[k] == arr[i]){
while (arr[i - count1] == arr[i]){
if ((i - count1) == k){
break ok;
}
++count1;
}
swap(arr, k, i - count1++);
}
}
ok:for (int k = end; k > j + count2; k--) {
if (arr[k] == arr[j]){
while (arr[j - count2] == arr[j]){
if ((j + count2) == k){
break ok;
}
++count2;
}
swap(arr, k, j + count2++);
}
}
if (start < i){
quickSort4(arr, start, i - count1);
}
if (j < end){
quickSort4(arr, j + count2, end);
}
}
上面是作为一个小菜比的总结,如有不当之处,请大家指出,多多包涵