归并排序java
这是一种分治法的应用,就是对于一个待排序的序列,将它一分为二,二分为四……,分到最后,每个序列中只会包含一个元素,这时,每个小序列就已经有序了(由于只有一个元素,因此确定是有序的)。而后将其两两归并排序,……四合为二,二合为一。这样就能完排序功能。算法
该排序算法有两个方法:数组
1.合并方法merge(),合并一个在某一位置分开,两边子序列分别有序的序列。code
2.归并排序方法mergeSort(),这个方法递归调用,完成序列的拆分排序。
排序
/** * @Description 合并排序一个在startIndex到minIndex位置有序,且在midIndex到endIndex上有序的序列 * @param srcArray * 源数组,且该数组在startIndex到midIndex位置上有序,在midIndex到endIndex上有序 * @param targetArray * 目标数组,排序完成以后的数组,起始位置为srcArray的起始位置 * @param startIndex * 排序开始位置 (不必定在srcArray的开始位置) * @param midIndex * 排序中间位置 * @param endIndex * 排序结束位置 * @return */ public static void merge(int[] srcArray, int[] targetArray, int startIndex, int midIndex, int endIndex) { // 注意目标数组的起始位置k是startIndex,而非0,由于srcArray的起始位置要和targetArray中的起始位置相同 int i = startIndex, j = midIndex + 1, k = startIndex; // 这里i,j用来指示由srcArray拆分出的两个有序子序列的起始位置 // 当某一个数组中的数字已经用完,那么就不用再循环比较了,直接将另外一个数组中剩下的数字拼接到新数组中便可 while (i < midIndex + 1 && j < endIndex + 1) { if (srcArray[i] < srcArray[j]) { targetArray[k++] = srcArray[i++]; } else { targetArray[k++] = srcArray[j++]; } } // 若是startIndex到midIndex数组中还剩下有数,那么将其拼接到目标数组targetArray中 while (i < midIndex + 1) { targetArray[k++] = srcArray[i++]; } // 若是midIndex到endIndex数组中还剩下有数,那么将其拼接到目标数组targetArray中 while (j < endIndex + 1) { targetArray[k++] = srcArray[j++]; } } /** * @Description 归并排序(递归),这个方法为何须要一个开始位置和结束位置?由于这个数组在递归排序过程当中逻辑上会拆分红不少小序列, * (一分为二,二分为四……) 直到一个序列只包含一个数为止, * 而这个startIndex和endIndex则是指示这些逻辑上的小数组在源数组中的正确位置。 * @param srcArray * 待排序数组 * @param targetArray * 目标数组 * @param startIndex * 开始位置 * @param endIndex * 结束位置 * @return */ public static void mergeSort(int[] srcArray, int[] targetArray, int startIndex, int endIndex) { int midIndex; int[] tempArray = new int[1024]; // 该数组为临时数组,大小须要按照须要进行更改,必须>=源数组 // 特别注意:这是递归的出口,也就是指当序列一分为二,二分为四……,当序列被折分到子序列中只剩下一个元素的时候, // 那么这个子序列就算是有序序列了(由于有一个元素,因此确定算是有序列的)。 // 将其直接存放于target目标数组中便可 if (startIndex == endIndex) { targetArray[startIndex] = srcArray[startIndex]; } else { midIndex = (startIndex + endIndex) / 2; mergeSort(srcArray, tempArray, startIndex, midIndex); // 递归排序左边的序列 mergeSort(srcArray, tempArray, midIndex + 1, endIndex); // 递归排序右边的序列 merge(tempArray, targetArray, startIndex, midIndex, endIndex); // 递归将排序好的序列(存放于temp中)进行2路归并 } }