排序算法(五)
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 }