Java 归并排序

归并排序,归并排序的重点在于数组的合并,正确理解其中的每一步对于整体的掌握很有帮助。

代码如下:

package com.vgbh;

/*
 * 归并排序
 */


public class MergeSorting {

    /*
     * 两路归并排序算法思路:
     * 1.把 n个记录看成 n个长度为1的有序子表;
     * 2.进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表; 
     * 3.重复第2步直到所有记录归并成一个长度为 n的有序表为止。
     */

    /*
     * 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。
     * 该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
     * 算法步骤:
     * 1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
     * 2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
     * 3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
     * 4. 重复步骤3直到某一指针达到序列尾
     * 5. 将另一序列剩下的所有元素直接复制到合并序列尾
    */

    private static int n = 10 ;//数组长度
    private static int[] arr = new int[n] ;//数组

    static PublicOut pc = null ;//定义外部对象

    public static int count = 0;//运行次数

    public static void main(String[] args) {
        pc = new PublicOut();
        pc.data(arr, n);
        System.out.println("排序前:");
        pc.prin(arr, n);

        MergeSorting ms = new MergeSorting();
        ms.merge(arr, n);

        System.out.println("排序后:");
        pc.prin(arr, n);

        System.out.println("最后共运行" + count + "次。");

    }

    public void merge (int arr[],int n) {
        int[] temp = new int[n];
        mergeSort(arr,0,n-1,temp);
    }

    /*
     * 归并排序,使用递归
     */
    public void mergeSort (int arr[],int first,int last,int temp[]) {
        if (first < last) {
            int bin = (first + last) / 2;
            mergeSort(arr,first,bin,temp);//左边
            mergeSort(arr,bin+1,last,temp);//右边
            mergeArray(arr,first,bin,last,temp);//数组排序
        }
    }

    /*
     * 合并数组
     * 首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。
     *  然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可
     */
    public void mergeArray (int arr[],int first,int bin,int last,int temp[]) {
        int i = first;//第一个数组的开始位
        int m = bin;//第一个数组的末尾值
        int j = bin + 1;//第二个数组的开始位
        int n = last;//第二个数组的末尾值
        int k = 0;//替补数组长度值

        //System.out.println("开始合并数组: i ,m  ,j , n , k " + i + m + j + n + k);

        //将数组分割为两部分,两部分进行比较,进行排序,排序后放在替补数组中,最终将排序好的数组返回到原数组。
        //再比对过程中,会首先将某个分数组中的值比对完后,在进行全部赋值操作。(注意观察赋值完成后i和j的值)
        while (i<=m && j<=n) {
            if (arr[i] <= arr[j]) {
                //temp[k] = arr[i];     k++;            i++;
                temp[k++] = arr[i++];
                //System.out.println("temp[k]  " + temp[k-1] + "    k " + (k-1) + "   i " + i + "这里是i");
                count++;
            } else {
                //temp[k] = arr[j];     k++;            j++;
                temp[k++] = arr[j++];
                //System.out.println("temp[k]  " + temp[k-1] + "    k " + (k-1) + "   j " + j + "这里是j");
                count++;
            }
        }

        while (j <= n) {//补偿未排序进数组的数
            //temp[k] = arr[j];         k++;            j++;
            temp[k++] = arr[j++];
            //System.out.println("temp[k]" + temp[k-1] + "    k" + (k-1) + "   j" + j);
            count++;
        }

        while (i <= m) {//补偿未排序进数组的数
            //temp[k] = arr[i];         k++;            i++;
            temp[k++] = arr[i++];
            //System.out.println("temp[k]  " + temp[k-1] + "    k  " + (k-1) + "   i  " + i);
            count++;
        }

        for (int x=0;x<k;x++) {
            arr[first+x] = temp[x];
            //System.out.println(temp[x] + "    最后的交换值    temp[x]");
        }

    }

}

注释的有一部分是简化版的代码,不理解的可以看另外一种。

注释的部分是测试用的代码,如果想要测试的话,看清楚每个部分的运行情况。

有问题的可以联系我的邮箱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vgbh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值