分治法算法——归并排序

来源:互联网 发布:java角色权限 编辑:程序博客网 时间:2024/05/16 08:08

分治法算法中的经典——归并排序

上一节,我讲了分治法的相关思想,并贴出数字旋转方阵的代码以及解决思想。算法的话,主要还是要靠自己领悟,要多思考,不会再去看看别人的思路。以下,我分析一下分治法算法中的经典——归并排序。

下面举个例子:
有个int数组,元素为{1,6,2,7,4,9}
这里写图片描述
首先,我们先将整个数组分解,分解成一个个规模大小相同的子问题,直到只有一个元素(图中第四行)。现在,我们再进行合并(图中第五六七行)。
合并的时候,就是将两个数组不断进行合并。以下是我的代码,里面有详细的注释。

show you my code :

import java.util.Scanner;/** * 归并排序 *  * @author chenjuxnu * @since 2016-1-20 *  */public class Main {    public static void main(String[] args) {        Scanner scan = new Scanner(System.in);        /** 输入数组的长度 */        int num = scan.nextInt();        /** 用于存放数据的数组 */        int arr[] = new int[num];        /** 用于合并数据的数组 */        int result[] = new int[num];        /** 将控制台的内容输入至数组内 */        for (int i = 0; i < num; i++) {            arr[i] = scan.nextInt();        }        scan.close();        /** 调用归并方法 */        MergeSort(0, num - 1, arr, result);        /** 输出内容 */        for (int i = 0; i < num; i++) {            System.out.print(result[i] + " ");        }    }    /**     * 归并排序的递归方法     *      * @param start     *            数组的开始值     * @param end     *            数组的结束值     * @param arr     *            存放用户输入数据的数组     * @param result     *            用于存放合并后的数组     */    public static void MergeSort(int start, int end, int arr[], int result[]) {        /** 用于保存中间值 */        int m;        // 如果开始下标等于结束下标,则结束递归        if (start == end) {            return;        } else {            m = (start + end) / 2;            // 递归调用左部分数据            MergeSort(start, m, arr, result);            // 递归调用右部分数据            MergeSort(m + 1, end, arr, result);            // 合并数组            Merge(arr, start, m, end, result);            // 将排序好的子序列放会到arr数组里            for (int i = start; i <= end; i++) {                arr[i] = result[i];            }        }    }    /**     * 用于合并数组的内容,并放到result数组内     *      * @param arr     *            需要合并的数组     * @param start     *            需要合并的数组的开始下标     * @param mid     *            需要合并的数组的(开始下标+结束下标)/2     * @param end     *            需要合并的数组的结束下标     * @param result     *            用于存放合并后的数组     */    public static void Merge(int arr[], int start, int mid, int end,            int result[]) {        /** 用于记录需要合并的第二个数组的下标 */        int j = mid + 1;        /** 用于记录result数组的下标 */        int num = start;        // 如果需要合并的第一个数组跟第二个数组均有数值可以比较        while (start <= mid && j <= end) {            if (arr[start] < arr[j]) {                result[num++] = arr[start++];            } else {                result[num++] = arr[j++];            }        }        // 如果需要合并的第二个数组没数值了,就将第一个数组依次放入result数组内        while (start <= mid) {            result[num++] = arr[start++];        }        // 如果需要合并的第一个数组没数值了,就将第二个数组依次放入result数组内        while (j <= end) {            result[num++] = arr[j++];        }    }}
0 0