1 /**
2 * 合并排序是建立在归并操作上的一种有效的排序算法。最差,平均和最好都是O( nlogn ),空间复杂度O(n)
3 * 该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。值得注意的是归并排序是一种稳定的排序方法。
4 * 归并操作的工作原理如下:
5 * 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
6 * 第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
7 * 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
8 * 重复步骤3直到某一指针超出序列尾
9 * 将另一序列剩下的所有元素直接复制到合并序列尾
10 * @author Burke
11 *
12 */
13
14
15 public class MergeSort {
16 public static void main(String[] args) {
17
18 int[] a = {4, 2, 1, 6, 3, 0, -5, 1, 1};
19 mergeSort(a, 0, a.length - 1);
20
21 for (int i = 0; i < a.length; i++) {
22 System.out.printf("%d ", a[i]);
23 }
24 }
25 public static void merge(int array[], int start1, int end1, int start2, int end2) {
26 int i, j;
27
28 i = start1;
29 j = start2;
30
31 int k = 0;
32 //建立一个临时长度为两个子序列长度之和的数组
33 int[] temp = new int[end2 - start1 + 1];
34 //通过循环,依次从两个子列表中找出较大的元素放人临时数组中
35 while(i <= end1 && j <= end2){
36 if(array[i] > array[j]){
37 temp[k++] = array[j++];
38 }
39 else
40 temp[k++] = array[i++];
41 }
42 //保存没有归并的部分
43 while(i <= end1){
44 temp[k++] = array[i++];
45 }
46 while(j <= end2){
47 temp[k++] = array[j++];
48 }
49 k=start1;
50 for(int element:temp){
51 array[k++] = element;
52 }
53
54 }
55 public static void mergeSort(int array[], int start, int end){
56 if(start < end){
57 // 两路归并
58 int mid = (start + end) / 2;
59 mergeSort(array, start, mid);
60 mergeSort(array, mid+1, end);
61 merge(array, start, mid, mid+1, end);
62 //多路归并
63 /*int mid = (start + end) / 4;
64 mergeSort(array, start, 1 * mid);
65 mergeSort(array, 1 * mid + 1, 2 * mid);
66 mergeSort(array, 2 * mid + 1, 3 * mid);
67 mergeSort(array, 3 * mid + 1, end);
68
69 merge(array, start, 1 * mid, 1 * mid +1,2 * mid);
70 merge(array, 2 * mid + 1, 3* mid, 3 * mid +1, end);
71 merge(array, start, 2 * mid, 2 * mid +1,end);
72 */
73 }
74 }
75 }