分治法算法——归并排序

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

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

下面举个例子:
有个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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值