Implementación de merge sort (recursiva y no recursiva)

(Dos puntos) Fusionar y clasificar, de hecho, es fusionar de dos en dos para garantizar que cada grupo esté en orden (al principio, solo un elemento de cada grupo debe estar en orden), y se garantiza que los dos grupos estén en orden. en orden después de la fusión. Debido a que hay un proceso de comparación durante la fusión, el más pequeño de los dos grupos se coloca primero en el grupo de fusión, y después de que uno de los dos grupos no tenga elementos, el otro grupo de elementos se lleva directamente al grupo de fusión. El gran grupo resultante, la matriz completa, también se ordena.

Implementación recursiva:

/**
     * 归并排序(递归)
     * @param array 待排序数组
     */
    private static void mergeSort(int[] array) {
        if (array==null || array.length<2) {
            return;
        }

        mergeSort(array, 0 , array.length-1);
    }

    /**
     * 根据边界归并排序边界内部分
     * @param array 待排序数组
     * @param l 左边界(含)
     * @param r 右边界(含)
     */
    private static void mergeSort(int[] array, int l, int r) {
        if (l >= r) return;

        // 中间位置不用 l+r/2 的原因是数组很大时,l+r会溢出
        int mid = l + ((r-l) >> 1);
        // 左部分排序
        mergeSort(array, l, mid);
        // 右部分排序
        mergeSort(array, mid+1, r);
        // 两个部分排序后的结果进行合并
        merge(array, l, mid, r);
    }

    /**
     * 两个排序好的部分进行合并成一个有序部分
     * @param array 数组
     * @param l 左边界(含)
     * @param mid 中间位置角标
     * @param r 右边界(含)
     */
    private static void merge(int[] array, int l, int mid, int r) {
        int[] help = new int[r-l+1];
        int index = 0;
        int leftCursor = l;
        int rightCursor = mid+1;
        /*游标在两部分都未越界*/
        while (leftCursor <= mid && rightCursor<=r) {
            if (array[leftCursor] < array[rightCursor]) {
                help[index++] = array[leftCursor++];
            } else if (array[leftCursor] > array[rightCursor]) {
                help[index++] = array[rightCursor++];
            } else {
                help[index++] = array[leftCursor++];
                help[index++] = array[rightCursor++];
            }
        }

        /*右部分越界,左部分剩余的值直接拿过来*/
        while (leftCursor <= mid) {
            help[index++] = array[leftCursor++];
        }

        /*左部分越界,右部分剩余的直接拿过来*/
        while (rightCursor <= r) {
            help[index++] = array[rightCursor++];
        }

        /*辅助数组替换原有数组*/
        index=0;
        while (l <= r) {
            array[l++] = help[index++];
        }
    }

Implementación no recursiva:
 

/**
     * 归并排序(非递归)
     * @param array 待排序数组
     */
    private static void mergeSortV2(int[] array){
        if (array==null || array.length<2) {
            return;
        }

        int length = array.length;
        int groupSize = 1;// 分组大小
        /*分组大小大于或等于就不用排序合并了*/
        while (groupSize < length) {
            int groupNum = length/groupSize;// 判断可以分多少组。需要注意可能后面还有不够一组的部分
            boolean moreGroup = length % groupSize > 0;// 是否还有不够一组的
            int l = 0;
            for (int i = 0; i < groupNum; i+=2) {
                int mid = l + groupSize - 1, r = mid + groupSize;// 左右边界
                if (r > length-1) {
                    if (! moreGroup) {
                        break;
                    } else {
                        r = length-1;
                    }
                }
                merge(array, l, mid, r);
                l = r + 1;
            }


            /*为防止groupSize溢出,需要做个判断*/
            if (groupSize > (length >> 1)) {
                break;
            } else {
                groupSize <<= 1;
            }
        }
    }

La dificultad de la clasificación no recursiva: necesidad de controlar el límite de la matriz y el límite del tamaño del grupo.

Al comparar las dos implementaciones recursivas y no recursivas, se puede encontrar que los dos códigos en realidad hacen lo mismo, el orden de ejecución del tipo de combinación es el mismo, pero el proceso de pensamiento es inverso.

Supongo que te gusta

Origin blog.csdn.net/u011471105/article/details/119617510
Recomendado
Clasificación