归并排序及其应用

1.归并排序代码先贴 上

 1 public static void merge_sort(int[] A, int l, int r){
 2         int m = (l + r)/2;
 3         if(l == r)
 4             return;
 5         merge_sort(A,l,m);
 6         merge_sort(A,m+1,r);
 7         merge(A,l,m,r);
 8     }
 9 
10     public static void merge(int [] A, int l, int m, int r){
11         int [] help = new int [r - l + 1];
12         int i = l, j = m+1,k = 0;
13         while(i <= m && j <= r){
14             help[k++] = A[i] < A[j]? A[i]:A[j];
15             i = A[i] < A[j]? i + 1: i;
16             j = A[i] < A[j]? j : j + 1;
17         }
18 
19         while(i <= m){
20             help[k++] = A[i++];
21         }
22         while(j <= r){
23             help[k++] = A[j++];
24         }
25         for (int n = l; n <= r; n++) {
26             A[n] = help[n-l];
27         }
28     }
View Code

时间复杂度 O(nlogn)

2。应用

主要是小和问题和逆序对问题,还有其他一些变形。只要是看到一些左右相互比较,左边比右边大。。。。都可以往归并上思考

a.小和问题

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组
的小和。
例子:
[1,3,4,2,5]
1左边比1小的数,没有;
3左边比3小的数,1;
4左边比4小的数,1、3;
2左边比2小的数,1;
5左边比5小的数,1、3、4、2;
所以小和为1+1+3+1+1+3+4+2=16

 1 package chuji;
 2 
 3 import java.util.*;
 4 /*
 5     小和问题
 6 在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组
 7 的小和。
 8 例子:
 9 [1,3,4,2,5]
10 1左边比1小的数,没有;
11 3左边比3小的数,1;
12 4左边比4小的数,1、3;
13 2左边比2小的数,1;
14 5左边比5小的数,1、3、4、2;
15 所以小和为1+1+3+1+1+3+4+2=16
16  */
17 public class xiaohe {
18     public static int getX(int [] A){
19         return merge_sort(A,0,A.length-1);
20     }
21 
22     public static int merge_sort(int [] A,int l,int r){
23         if(l >= r)
24             return 0;
25         int m = (l + r)/2;
26         return merge_sort(A,l,m) + merge_sort(A,m+1,r) + merge(A,l,m,r);
27     }
28 
29     public static int merge(int [] A,int l,int m,int r){
30         int [] help = new int[r - l +1];
31         int a = l;
32         int b = m+1;
33         int k = 0;
34         int ans = 0;
35         while(a <= m && b <= r){
36             help[k++] = A[a] < A[b]? A[a] : A[b];
37             if(A[a] < A[b]){ 
38                 ans += A[a] * (r - b + 1);    // 在归并排序的基础上就加这句
39             }
40             a = A[a] < A[b] ? a+1:a;
41             b = A[a] < A[b] ? b : b+1;
42         }
43         while(a<=m){
44             help[k++] = A[a++];
45         }
46         while(b<m){
47             help[k++] = A[b++];
48         }
49         for (int i = 0; i < k; i++) {
50             A[l+i] = help[i];
51         }
52         return ans;
53     }
54 
55     public static void main(String[] args) {
56         int [] A = {1,3,4,2,5};
57         System.out.println(getX(A));
58     }
59 }

b.逆序对问题

在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序

对。

 1 package chuji;
 2 
 3 import java.util.*;
 4 
 5 /*
 6 逆序对问题
 7 在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序
 8 对。
 9  */
10 
11 public class nixudui {
12     public static void printnixu(int [] A){
13         merge_sort(A,0,A.length-1);
14     }
15 
16     public static void merge_sort(int [] A,int l,int r){
17         if(l >= r)
18             return;
19         int m = (l+r)/2;
20         merge_sort(A,l,m);
21         merge_sort(A,m+1,r);
22         merge(A,l,m,r);
23     }
24     public static void merge(int [] A,int l,int m,int r){
25         int [] help = new int[r - l + 1];
26         int x = l;
27         int y = m+1;
28         int k = 0;
29         while(x <= m && y <= r){
30 
31             help[k++] = A[x] < A[y] ? A[x] : A[y];
32             if(A[x] > A[y])
33                 System.out.println(A[x] + "----" + A[y]);
34             x = A[x] < A[y] ? x+1:x;
35             y = A[x] < A[y] ? y : y+1;
36         }
37         while(x<=m){
38             help[k++] = A[x++];
39             if(x<=m){
40                 for (int i = m+1; i <= r; i++) {                //左边剩余的话,与右边所有元素形成逆序对
41                     System.out.println(A[x] + "----"+ A[i]);
42                 }
43             }
44 
45 
46         }
47         while(y<=r){
48             help[k++] = A[y++];
49         }
50         for (int i = 0; i < k; i++) {
51             A[l+i] = help[i];
52         }
53 
54     }
55 
56     public static void main(String[] args) {
57         int [] A = {4,3,2,1};
58         printnixu(A);
59     }
60 }

猜你喜欢

转载自www.cnblogs.com/ycf5812/p/10791766.html