快速排序Java模板 详情参考 https://www.acwing.com/problem/content/787/ https://www.acwing.com/solution/content/2096/
快速排序的整体过程,动态变化流程
以从小到大排序为例
- 选择一个目标参考值
p
i
v
i
t
pivit
pivit,通常课本上会说选择数组的第一个元素,但是如果本身数组就已经是从小到大有序了的话,这个时候效率是最差的,会退化到
O
(
n
2
)
O(n^{2} )
O(n2)。因此我们这里选择中间位置的元素作为参考值
通常的、没有经过充分考虑的选择是将第一个元素做为"基准“。如果输入书随机的,那么这是可以接受的,但是如果输入是预排序的或是反序的,那么这样的”基准“就是一个劣质的分割,因为所以的元素不是被划入S1就是被划入S2。实际上,如果第一个元素用作”基准“而且输入是预先排序的,那么快速排序花费的时间将是二次的,可是实际上却没干什么事,因此,使用第一个元素作为”基准“是绝对糟糕的。
- 从前往后找到一个不比目标元素值小的元素
n
u
m
s
[
i
]
nums[i]
nums[i]
- 从后往前找到一个不必目标元素值大的元素
n
u
m
s
[
j
]
nums[j]
nums[j]
- 如果
i
<
j
i < j
i<j,那么直接进行交换
n
u
m
s
[
i
]
nums[i]
nums[i]和
n
u
m
s
[
j
]
nums[j]
nums[j]的值
- 递归处理从
l
l
l到
j
j
j,以及从
j
+
1
j + 1
j+1到
r
r
r的
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(reader.readLine());
int[] arr = new int[n];
String[] s = reader.readLine().split(" ");
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(s[i]);
}
quickSort(arr, 0, n - 1);
for (int i = 0; i < n; i++) {
writer.write(arr[i] + " ");
}
writer.write("\n");
writer.flush();
writer.close();
reader.close();
}
public static void quickSort(int[] q, int l, int r) {
if (l >= r) {
return;
}
int pivit = q[l + r >> 1];
int i = l - 1;
int j = r + 1;
while (i < j) {
do {
i++;
} while (pivit > q[i]);
do {
j--;
} while (pivit < q[j]);
if (i < j) {
int tmp = q[i];
q[i] = q[j];
q[j] = tmp;
}
}
quickSort(q, l, j);
quickSort(q, j + 1, r);
}
}
|