AcWing785快速排序
题目:
题目大意:
快排。
数据范围:
如图所示
思路:
模板,固定写法。递归的处理每个区间,首先选取此次递归中区间(l, r)内的一个数mid(一般是中间数),经过不断交换将该区间中小于mid的数放在mid左边,大于mid的数放在mid右边,然后递归处理区间(l, j)、(j + 1, r)区间。注意:该区间只有一个数时(l >= r),递归结束。
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static int N = 100010;
public static int[] nums = new int[N];
public static void quickSort(int[] nums, int l, int r){
// 区间内只有一个数字时结束递归
if (l >= r)
return;
//不能让 mid = l + r >> 1,因为 num[mid] 会改变。
int mid = nums[l + r >> 1];
//交换时i的初始值为l - 1,以保证选择到第一个大于mid的数num[i]
//交换时j的初始值为r + 1,以保证选择到第一个小于mid的数num[j]
int i = l - 1, j = r + 1;
while (i < j){
while (nums[++ i] < mid);
while (nums[-- j] > mid);
//当i < j时才交换
if (i < j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
//递归的处理左(l,j)、右(j + 1,r)区间
quickSort(nums, l, j);
quickSort(nums, j + 1, r);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for (int i = 0; i < n; i ++ ){
nums[i] =scanner.nextInt();
}
quickSort(nums, 0, n - 1); //初始范围为(0,n-1)
for (int i = 0; i < n ; i ++ ){
System.out.print(nums[i] + " ");
}
}
}
时空复杂度分析等:
-
时间复杂度 :
- 平均:O(nlogn)。
- 最好:O(nlogn):当每次划分时,算法若都能分成两个等长的子序列时,分治算法效率达到最大。
- 最坏:O(n^ 2):待排序列有序时,相当于冒泡排序,时间复杂度为O(n^2)。
-
空间复杂度 :
- 最好:O(logn):当每次划分时,算法若都能分成两个等长的子序列时。
- 最坏:O(n):待排序列有序时,相当于冒泡排序。
-
稳定性:不稳定。
-
附: