归并排序(merge sort)

归并排序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路归并
        }
    }
相关文章
相关标签/搜索