java数据结构与算法-高级排序-归并排序

一、概述

1、基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,将每个子序列排成有序的。然后再把有序子序列合并为整体有序序列。
2、算法流程:(迭代+两个有序数列合并为一个有序数列)
3、时间复杂度:O(nlog(n)),归并算法是一种稳定排序算法。
4、归并排序示例:

 

二、归并排序实现代码如下:

package com.tool.wpn.quicksort;

import android.util.Log;

/**
 * Created by Xi on 2017/8/12.
 * 归并排序
 */

public class ArrayMerge {
    private long[] theArray;//需排序的数组
    private int nElems;//数组所函元素大小
    public ArrayMerge(int max){
        theArray=new long[max];
        nElems=0;
    }

    /**
     * 插入元素
     * @param value
     */
    public void insert(long value){
        theArray[nElems]=value;
        nElems++;
    }

    /**
     * 展示数组
     */
    public void display(){
        StringBuilder sb=new StringBuilder();
        sb.append("[");
        for(int i=0;i<nElems;i++){
            if(i==nElems-1)
                sb.append(theArray[i]);
            else {
                sb.append(theArray[i]);
                sb.append(",");
            }
        }
        sb.append("]");
        Log.v("ArrayMerge",sb.toString());
    }

    /**
     * 归并开始排序
     */
    public void mergeSort(){
        long[] workSpace=new long[nElems];//创建一个数组空间,用户归并排序使用
        recMergeSort(workSpace,0,nElems-1);
    }

    /**
     *左右拆分数组与归并
     * 界限范围都使用的是数组下标
     */
    private void recMergeSort(long[] workSpace,int lowerBound,int upperBound){
        if(lowerBound==upperBound)return;//若左边界==右边界,退出,即以划分为最小部分,无法再左右划分
        else{
            int mid=(lowerBound+upperBound)/2;
            recMergeSort(workSpace,lowerBound,mid);//递归前半部分排序处理
            recMergeSort(workSpace,mid+1,upperBound);//递归后半部分排序处理
            merge(workSpace,lowerBound,mid+1,upperBound);
        }
    }

    /**
     * 将左右排序完的数组合并成一个
     * @param workspace
     * @param lowPtr
     * @param highPtr
     * @param upperBound
     */
    private void merge(long[] workspace,int lowPtr,int highPtr,int upperBound){
        int j=0;
        int lowerBound=lowPtr;
        int mid=highPtr-1;
        int n=upperBound-lowerBound+1;//要归并的数量,由于lowerBound代表的数组下角标,所以需要加1
        while(lowPtr<=mid&&highPtr<=upperBound){//从左半部分的起点,又半部分起点,开始比对大小,直到左半部分或右半部分元素比对完即结束循环
            if(theArray[lowPtr]<theArray[highPtr])
                workspace[j++]=theArray[lowPtr++];
            else
                workspace[j++]=theArray[highPtr++];
        }
        while(lowPtr<=mid)//若左半部分未循环比较完,则将剩下的部分元素添加排序完的数组中
            workspace[j++]=theArray[lowPtr++];
        while(highPtr<=upperBound)//若右半部分未循环比较完,则将剩下的元素添加到排序完的数组中
            workspace[j++]=theArray[highPtr++];
        for(j=0;j<n;j++)
            theArray[lowerBound+j]=workspace[j];//将排序完毕的元素复制到theArry真正在的位置中
    }
}


二、主调用函数如下:


 /**
     * 归并排序,使用递归
     * 原理为:使用递归原理,将数组从中间分为两部分,然后分别对左右两部分进行排序,然后再将左右两部分进行合并。
     * 具体步骤就是,先将数组从中间利用递归分为左右,直到分成最小的左右部分,即左1个元素,右一个元素。
     * 然后再将划分的最小部分进行合并,合并成有序。
     * 按照上一步的合并办法,从小范围到大范围,最终合并成有序的数组。
     * 时间复杂度为:O(N*logN),即需排序的数组大小为10000,则需要40000
     */
    private void sortMerge(){
        ArrayMerge array=new ArrayMerge(20);
        array.insert(20);
        array.insert(10);
        array.insert(30);
        array.insert(40);
        array.insert(5);
        array.insert(7);
        array.insert(50);
        array.insert(90);
        array.insert(110);
        array.insert(8);
        array.insert(130);
        array.insert(70);
        array.display();
        array.mergeSort();
        array.display();
    }

日志打印如下:

08-15 10:35:17.334 25472-25472/com.tool.wpn.quicksort V/ArrayMerge: [20,10,30,40,5,7,50,90,110,8,130,70]
08-15 10:35:17.335 25472-25472/com.tool.wpn.quicksort V/ArrayMerge: [5,7,8,10,20,30,40,50,70,90,110,130]

源码下载地址:点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值