归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

分治算法的一般步骤:

(1)分解,将要解决的问题划分成若干规模较小的同类问题;

(2)求解,当子问题划分得足够小时,用较简单的方法解决;

(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解

首先考虑下如何将将二个有序数列合并。

合并两个有序的数组:

import java.util.Arrays;

public class Main {
    static int[] arr={1,3,5};
    static int[] arr2={2,4,6};
    public static void main(String[] args) throws InterruptedException {
     
        int[] c= MemeryArray(arr,arr2);
        System.out.println(Arrays.toString(c));
    }

    //将有序数组a[]和b[]合并到c[]中
    static int[] MemeryArray(int[] a,int[] b)
    {
        int n=a.length;
        int m=b.length;
        int[] c=new int[m+n];
        int i, j, k;

        i = j = k = 0;
        while (i < n && j < m)
        {
            if (a[i] < b[j])
                c[k++] = a[i++];
            else
                c[k++] = b[j++];
        }

        while (i < n)
            c[k++] = a[i++];

        while (j < m)
            c[k++] = b[j++];
        return c;
    }
}
[1, 2, 3, 4, 5, 6]
View Code

比较两个数组的第一个元素,选取其中较小的元素,假设数组为a,b,a[0]较小,选取a[0]赋值到c[0]

比较a[1]与b[0],选取其中较小的赋值到数组c

......

上面代码中最后的

while(i<n)/while(j<m) 是防止一个数组已经遍历合并完了,但是另外一个还没有合并完,再次进行合并。

============================================================

归并排序:

import java.util.Arrays;

public class Main {
    static  int[] array = {7, 8, 9, 6, 1, 4, 3, 2, 5, 0, -1, -2,-3};
    public static void main(String[] args) throws InterruptedException {
        System.out.println(Arrays.toString(array));
        mergeSort(array);
        System.out.println(Arrays.toString(array));
    }

    //归并排序
    public static void mergeSort(int[] array){
        int[] workSpace = new int [array.length]; //用于辅助排序的数组
        recursiveMergeSort(array,workSpace,0,workSpace.length-1);
    }

    /**
     * 递归的归并排序
     * @param workSpace  辅助排序的数组
     * @param lowerBound 欲归并数组段的最小下标
     * @param upperBound 欲归并数组段的最大下标
     */
    private static void recursiveMergeSort(int[] array,int[] workSpace,int lowerBound,int upperBound){

        if(lowerBound== upperBound){  //该段只有一个元素,不用排序
            return;
        }else{
            int mid = (lowerBound+upperBound)/2;
            recursiveMergeSort(array,workSpace,lowerBound,mid);    //对低位段归并排序
            recursiveMergeSort(array,workSpace,mid+1,upperBound);  //对高位段归并排序
            merge(array,workSpace,lowerBound,mid,upperBound);
            System.out.print("lowerBound:"+lowerBound+",mid:"+mid+",upperBound:"+upperBound+"     ");
            display(array);
        }
    }

    /**
     * 对数组array中的两段进行合并,lowerBound~mid为低位段,mid+1~upperBound为高位段
     * @param workSpace 辅助归并的数组,容纳归并后的元素
     * @param lowerBound 合并段的起始下标
     * @param mid 合并段的中点下标
     * @param upperBound 合并段的结束下标
     */
    private static void merge(int[] array,int [] workSpace,int lowerBound,int mid,int upperBound){

        int lowBegin = lowerBound;  //低位段的起始下标
        int lowEnd = mid;           //低位段的结束下标
        int highBegin = mid+1;  //高位段的起始下标
        int highEnd = upperBound;  //高位段的结束下标
        int j = 0; //workSpace的下标指针
        int n = upperBound-lowerBound+1;  //归并的元素总数

        while(lowBegin<=lowEnd && highBegin<=highEnd){
            if(array[lowBegin]<array[highBegin]){//将两者较小的那个放到workSpace中
                workSpace[j++]= array[lowBegin++];
            }else{
                workSpace[j++]= array[highBegin++];
            }
        }

        while(lowBegin<=lowEnd){
            workSpace[j++]= array[lowBegin++];
        }

        while(highBegin<=highEnd){
            workSpace[j++]= array[highBegin++];
        }

        for(j=0;j<n;j++){  //将归并好的元素复制到array中
            array[lowerBound++]= workSpace[j];
        }
    }

    //按顺序打印数组中的元素
    public static void display(int[] array){
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+"\t");
        }
        System.out.println();
    }
}
[7, 8, 9, 6, 1, 4, 3, 2, 5, 0, -1, -2, -3]
lowerBound:0,mid:0,upperBound:1     7    8    9    6    1    4    3    2    5    0    -1    -2    -3    
lowerBound:2,mid:2,upperBound:3     7    8    6    9    1    4    3    2    5    0    -1    -2    -3    
lowerBound:0,mid:1,upperBound:3     6    7    8    9    1    4    3    2    5    0    -1    -2    -3    
lowerBound:4,mid:4,upperBound:5     6    7    8    9    1    4    3    2    5    0    -1    -2    -3    
lowerBound:4,mid:5,upperBound:6     6    7    8    9    1    3    4    2    5    0    -1    -2    -3    
lowerBound:0,mid:3,upperBound:6     1    3    4    6    7    8    9    2    5    0    -1    -2    -3    
lowerBound:7,mid:7,upperBound:8     1    3    4    6    7    8    9    2    5    0    -1    -2    -3    
lowerBound:7,mid:8,upperBound:9     1    3    4    6    7    8    9    0    2    5    -1    -2    -3    
lowerBound:10,mid:10,upperBound:11     1    3    4    6    7    8    9    0    2    5    -2    -1    -3    
lowerBound:10,mid:11,upperBound:12     1    3    4    6    7    8    9    0    2    5    -3    -2    -1    
lowerBound:7,mid:9,upperBound:12     1    3    4    6    7    8    9    -3    -2    -1    0    2    5    
lowerBound:0,mid:6,upperBound:12     -3    -2    -1    0    1    2    3    4    5    6    7    8    9    
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
View Code

http://blog.csdn.net/u012152619/article/details/47345107

优质内容筛选与推荐>>
1、jQuery CSS 选择器
2、状态,
3、.net 事件
4、远程桌面连接:出现身份验证错误 要求函数不受支持
5、爬取全本小说内容并进行文本分析


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn