归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
算法:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
import java.util.*; public class Main1 { static int a[] = new int[10010]; static int b[] = new int[10010]; public static void sort(int a[], int l, int r) { if (r - l > 0) { int mid = (r + l) / 2; int i = l; int p = l; int q = mid + 1; sort(a, l, mid); sort(a, mid + 1, r); while (p <= mid || q <= r) { if (q > r || (p <= mid && a[p] <= a[q])) //这一点是简化代码,包含了当后边数组没有比前一半大的时候 b[i++] = a[p++]; else { b[i++] = a[q++]; } } for (i = l; i <= r; i++) a[i] = b[i]; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); for (int i = 1; i <= n; i++) { a[i] = sc.nextInt(); } sort(a, 1, n); for (int i = 1; i <= n; i++) System.out.printf("%d ", a[i]); System.out.println(ans); } }
归并排序求逆序对
求序列的逆序对,先看下面的例子:
设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数为:3+4+4=11;
逆序数为14;
根据归并排序的特性(左右两部分的有序序列合并时,假设i在左边,j在右边,对于右边的j,统计左边比它大的元素个数s(j),则s(j) = mid-i+1 ,合并万所有的序列时即可得出答案,即f(j)之和便是答案),只需将上面的代码修改一处:把“else b[i++] = a[q++];”改成“ else {b[i++] = a[q++]; ans += mid-p+1;}" ,注意在调用之前将ans清零。
package demo2; import java.util.*; public class Main1 { static int a[] = new int[10010]; static int b[] = new int[10010]; static int ans = 0; public static void sort(int a[], int l, int r) { if (r - l > 0) { int mid = (r + l) / 2; int i = l; int p = l; int q = mid + 1; sort(a, l, mid); sort(a, mid + 1, r); while (p <= mid || q <= r) { if (q > r || (p <= mid && a[p] <= a[q])) b[i++] = a[p++]; else { b[i++] = a[q++]; ans += mid - p + 1; } } for (i = l; i <= r; i++) a[i] = b[i]; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); for (int i = 1; i <= n; i++) { a[i] = sc.nextInt(); } sort(a, 1, n); for (int i = 1; i <= n; i++) System.out.printf("%d ", a[i]); System.out.println(ans); } }
来源:https://www.cnblogs.com/ls-pankong/p/10504792.html