算法思想
1,申请空间,使其大小为2个已经排序的数列之和,该空间用来存放合并后的序列。
2,设定2个指针,最初位置为2个已经排序数列的的起始位置。
3,比较2个指针所指向的元素,选择较小的元素放入合并空间,并移动指针到下个位置。
4,重复步骤3,知道某一个指针到达数列尾部。
5,将另一个数列的剩余元素全部复制到合并空间。
归并排序原理
归并排序具体工作原理如下(假设序列共有n个元素):
- 将序列每相邻两个数字进行归并操作,形成个序列,排序后每个序列包含两个元素
- 将上述序列再次归并,形成个序列,每个序列包含四个元素
- 重复步骤2,直到所有元素排序完毕
归并排序原理代码
1 /** 2 *归并排序的原理Demo: 3 * 1,申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 4 * 2, 设定两个指针,最初位置分别为两个已经排序序列的起始位置 5 * 3, 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 6 * 4,重复步骤3直到某一指针达到序列尾 7 * 5,将另一序列剩下的所有元素直接复制到合并序列尾 8 * 9 */ 10 public class Merge 11 { 12 13 public static int[] mergeSort(int[] A,int[] B){ 14 //申请空间,大小等于2个已经排序的数列之和 15 int[] C = new int[A.length+B.length]; 16 //指针i,j分别指向2个数列的起始位置。 17 int i=0,j=0,k=0; 18 //比较2个指针所指向的元素,将较小的元素放入到合并空间,并移动指针。 19 while(i<A.length && j<B.length){ 20 if(A[i] < B[j]) 21 C[k++] = A[i++]; 22 else 23 C[k++] = B[j++]; 24 } 25 //将另一个序列的元素全部复制到合并空间尾部 26 //以下2个while只会执行其中一个 27 while(i<A.length){ 28 C[k++] = A[i++]; 29 } 30 while(j<B.length){ 31 C[k++] = B[j++]; 32 } 33 return C; 34 } 35 public static void main(String[] args) 36 { 37 int[] A = {1,3,5,7,9,11}; 38 int[] B = {2,4,6,8,10,12}; 39 int[] C =mergeSort(A, B); 40 for(int i: C) 41 { 42 System.out.print(i+" "); 43 } 44 } 45 }
Java 实现代码
1 public class Merge 2 { 3 4 public static void main(String[] args) 5 { 6 Integer[] arr = {5,3,4,6,3,1,4,6,5,36,5,44,22,88,99,5,555,3335,64,544,22333}; 7 merge(arr); 8 for(Integer i: arr) 9 { 10 System.out.print(i + " "); 11 } 12 } 13 14 @SuppressWarnings("unchecked") 15 private static <T extends Comparable<? super T>> void merge(T[] arr) 16 { 17 T[] temArr = (T[])new Comparable[arr.length]; 18 mergeSort(arr, temArr, 0, arr.length - 1); 19 } 20 21 private static <T extends Comparable<? super T>> void mergeSort(T[] arr, T[] temArr, int left, int right) 22 { 23 if(left < right) 24 {//递归 25 int center = (left + right) / 2; 26 mergeSort(arr, temArr, left, center); 27 mergeSort(arr, temArr, center + 1, right); 28 merge(arr, temArr, left, center + 1, right); 29 } 30 } 31 32 private static <T extends Comparable<? super T>> void merge(T[] arr, T[] temArr, int leftPos, int rightPos, int rightEnd) 33 { 34 // 左边数列的最大索引 35 int leftEnd = rightPos - 1; 36 // 合并空间的起始索引 37 int temPos = leftPos; 38 // 用于复制最终数组用的左边数列的起始指针 39 int temLeft = leftPos; 40 // 比较2个指针所指的元素的大小,将小的赋值给临时空间对应的位置。指针移动一个位置,继续比较。直到一个数列结尾。 41 while(leftPos <= leftEnd && rightPos <= rightEnd) 42 { 43 if(arr[leftPos].compareTo(arr[rightPos]) <= 0) 44 { 45 temArr[temPos++] = arr[leftPos++]; 46 } 47 else 48 { 49 temArr[temPos++] = arr[rightPos++]; 50 } 51 } 52 // 将另外一个数列全部复制到临时空间 53 while(leftPos <= leftEnd) 54 { 55 temArr[temPos++] = arr[leftPos++]; 56 } 57 while(rightPos <= rightEnd) 58 { 59 temArr[temPos++] = arr[rightPos++]; 60 } 61 // 将临时空间的值复制到对应位置的原来数组 62 for(int i = temLeft; i <= rightEnd; i++) 63 { 64 arr[i] = temArr[i]; 65 } 66 } 67 }