排序算法Java实现——归并排序

本文详细介绍了归并排序算法的基本思想、工作原理以及二路归并排序的实现过程,通过一个具体的JAVA代码示例展示了如何进行归并排序,并探讨了其时间复杂度和稳定性。归并排序的时间复杂度为O(nlog2n),但空间效率较低,因为它需要额外的存储空间。
摘要由CSDN通过智能技术生成

归并排序(也可以叫合并排序),其实归并排序的本质就是合并排序。

它是与插入排序、交换排序、选择排序不同的一类排序方法,不同之处在于:

它要求:待排序序列是由若干个有序子序列组成。

那么究竟什么是归并排序呢?归并这个词到底是什么意思?

首先可以理解为就是合并,然后就是这个词的由来,可以说归并这个词是个生造词。 “归并”由merge翻译而来,所以归并排序亦可以翻译为:”合并排序“。因为此算法的关键就在于合并。

一、基本思想

归并排序是将两个或两个以上的有序序列合并成一个新的有序序列。本篇文章介绍的就是归并排序主要是将两个有序数据序列合并成一个新的有序序列。

合并的方法是比较各子序列的第一个记录的键值,最小的一个就是排序的第一个记录的键值。取出这个记录,继续比较各子序列现有的第一个记录的键值,便可以找出排序后的第二个键值。然后开始递归,最终得到排序结果。

所以归并排序的基础就是合并

1)有序序列的合并

归并排序的核心是:两个有序子序列的合并。

此算法的执行时间为:O(n-h+1)。

这里就不上C++代码了。

2)二路归并排序

二路归并排序是将两个有序表合并成一个有序表的排序方法。

二路归并排序是稳定的。

归并排序算法的时间复杂度为O(nlog2n)

二、代码

C++代码很简单

...

JAVA代码挺复杂的

如下:

/*@(#)MergeSort.java   2017-4-25 
 * Copy Right 2017 Bank of Communications Co.Ltd.
 * All Copyright Reserved
 */

package com.sort.cn;

/**
 * TODO Document MergeSort
 * <p>
 * @version 1.0.0,2017-4-25
 * @author Singit
 * @since 1.0.0
 */
public class MergeSort {
	static int number=0;
    public static void main(String[] args) {
        int[] a = {24, 5, 98, 28, 99, 56, 34, 2 };
        printArray("排序前:",a);
        MergeSort(a);
        printArray("排序后:",a);
    }

    private static void printArray(String pre,int[] a) {
        System.out.print(pre+"\n");
        for(int i=0;i<a.length;i++)
            System.out.print(a[i]+"\t");    
        System.out.println();
    }

    private static void MergeSort(int[] a) {
        // TODO Auto-generated method stub
        System.out.println("开始排序");
        Sort(a, 0, a.length - 1);
    }

    private static void Sort(int[] a, int left, int right) {
        if(left>=right)
            return;
    
        int mid = (left + right) / 2;
        //二路归并排序里面有两个Sort,多路归并排序里面写多个Sort就可以了
        Sort(a, left, mid);
        Sort(a, mid + 1, right);
        merge(a, left, mid, right);

    }


    private static void merge(int[] a, int left, int mid, int right) {
    
        int[] tmp = new int[a.length];
        int r1 = mid + 1;
        int tIndex = left;
        int cIndex=left;
        // 逐个归并
        while(left <=mid && r1 <= right) {
            if (a[left] <= a[r1]) 
                tmp[tIndex++] = a[left++];
            else
                tmp[tIndex++] = a[r1++];
        }
            // 将左边剩余的归并
            while (left <=mid) {
                tmp[tIndex++] = a[left++];
            }
            // 将右边剩余的归并
            while ( r1 <= right ) {
                tmp[tIndex++] = a[r1++];
            }
            
            
           
            
            System.out.println("第"+(++number)+"趟排序:\t");
            // TODO Auto-generated method stub
            //从临时数组拷贝到原数组
             while(cIndex<=right){
                    a[cIndex]=tmp[cIndex];
                    //输出中间归并排序结果
                    System.out.print(a[cIndex]+"\t");
                    cIndex++;
                }
             System.out.println();
        }
}


 

输出结果:

排序前:
24	5	98	28	99	56	34	2	
开始排序
第1趟排序:	
5	24	
第2趟排序:	
28	98	
第3趟排序:	
5	24	28	98	
第4趟排序:	
56	99	
第5趟排序:	
2	34	
第6趟排序:	
2	34	56	99	
第7趟排序:	
2	5	24	28	34	56	98	99	
排序后:
2	5	24	28	34	56	98	99	


三、总结

从以上代码可以看出,归并排序算法需要递归的进行分解、合并,每进行一次归并排序需要调用一次merge()方法,每次执行merge()方法需要比较n次,

SO,

归并排序算法的时间复杂度为O(nlog2n)。

归并排序的空间效率较差。因为它需要一个与原始序列同样大小的辅助序列。

归并排序是稳定的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值