快排
思路:
第一步 确定分界点 x=q[l] q[r] q[l+r >>1] 任意数都可以
第二步 左右双指针调整数组,使x 所在位置右值皆大于x 左值皆小于x
第三步 递归处理左右两段数组
快排模板
import java.util.*;
import java.lang.*;
public class Main {
public static void main(String[] args) {
Scanner mc = new Scanner(System.in);
int n = mc.nextInt();
int[] q = new int[n];
for (int i = 0; i < n; i++) {
q[i] = mc.nextInt();
}
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) {
System.out.print(q[i]+" ");
}
}
static void quick_sort(int q[], int l, int r) {
if (l >= r) return;
int x = q[l + r >> 1], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) {
//两指针交换
int temp = 0;
temp = q[i];
q[i] = q[j];
q[j] = temp;
}
}
quick_sort(q, l, j); //递归
quick_sort(q, j + 1, r);
}
}
归并排序——分治
思路:
第一步 确定分界点 mid = l + r >> 1
第二步 对左右进行递归排序
第三步 归并 合二为一
动态图解:
import java.util.*;
import java.lang.*;
public class Main {
public static void main(String[] args) {
Scanner mc = new Scanner(System.in);
int n = mc.nextInt();
int[] q = new int[n];
for (int i = 0; i < n; i++) {
q[i] = mc.nextInt();
}
merge_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) {
System.out.print(q[i] + " ");
}
}
static void merge_sort(int q[], int l, int r) {
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
int[] tmp = new int[r+1];
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k++] = q[i++]; //取最小值
else tmp[k++] = q[j++];
while (i <= mid) tmp[k++] = q[i++]; //判界 指针后移
while (j <= r) tmp[k++] = q[j++];
for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}
}
小练:逆序对的数量
import java.util.*;
import java.lang.*;
public class Main {
public static void main(String[] args) {
Scanner mc = new Scanner(System.in);
int n = mc.nextInt();
int[] q = new int[n + 1];
for (int i = 0; i < n; i++) {
q[i] = mc.nextInt();
}
System.out.print(merge_sort(q, 0, n - 1));
}
static long merge_sort(int[] q, int l, int r) {
if (l >= r) return 0;
int mid = l + r >> 1;
long sum = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
int[] tmp = new int[r + 1];
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k++] = q[i++];
else {
sum += mid - i + 1; //
tmp[k++] = q[j++];
}
while (i <= mid) tmp[k++] = q[i++];
while (j <= r) tmp[k++] = q[j++];
for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
return sum;
}
}
来源:Acwing算法基础课