八大排序之归并排序

一、基本思想

  归并排序,将当前序列分成若干个小的有序序列,然后逐个合并成更大的有序序列。这里所谓的若干个小的有序序列即是将序列分割成n个长度为1的序列,然后两两合并成长度为二的有序序列。然后在将这长度为二的有序序列合并为长度为四的有序序列。依次类推,最终达到原序列长度,这样,排序就完成了。这其实是归并排序递归回溯过程的描述。归并排序的正序描述可以是这样,将序列分成两个子序列,对两个子序列进行归并排序,然后将两个子序列合并到原序列中。

二、实现步骤

  归并排序,有两个需要解决的问题:一、如何划分子区间。二、如何合并子区间。

  划分子区间:

  这里采用两路归并排序,即将当前序列划分成两个子序列。

  合并子区间:

  由于子区间是有序的,所以在合并过程中不会有很大的复杂度,一次遍历即可。

  思想已经陈述完毕,下面看代码,有详细注释。

三、实现代码

  随机数组测试类 点击这里

package sort;

import sort.util.*;

public class MergingSort implements ISort{ 

    //private static int[] c = null;
    //将有序序列a[left] ~ a[middle]和a[middle+1] ~ a[right]合并到数组b中,返回数组b
    private void merge(int[] a , int left ,  int middle , int right) {
        int[] b = new int[a.length];
        for(int i = 0; i < a.length; i++) {            //将数组a复制到b中
            b[i] = a[i];
        }
        int i = left ,  j = middle + 1 ,  k = left;
        while(i <= middle && j <= right) {             //合并过程,选择较小的,逐个赋值。
            if(b[i] < b[j]) a[k++] = b[i++];
            else a[k++] = b[j++];
        }                                              //循环结束,说明有一个有序序列已经遍历完毕
        while(i <= middle) {a[k++] = b[i++];}          //将剩余的部分直接复制到a数组中
        while(j <= right) {a[k++] = b[j++];}           //这两个循环只有一个能被执行

    }

    //对a[left] ~ a[right]进行归并排序,排序后的结果放在b[]中
    private void mergeSort(int[] a , int left , int right) {
        if(left != right) {                             //当进行归并排序的数组只有一个元素
            int middle = (left + right) / 2;            //划分成两部分进行归并
            mergeSort(a , left , middle);               //左边部分进行归并排序
            mergeSort(a , middle+1 , right);            //右边部分进行归并排序
            merge(a , left , middle , right);           //左右排序完成后进行合并
        }
    }

    public void sort(int[] array){
        mergeSort(array , 0 , array.length-1);
    }
    public static void main(String[] args) {
        int[] array = RandomArrayGenerator.getRandomArray(100 , 30);
        SortTestHelper.test(new MergingSort() , array);
    }
}

测试结果:

四、总结分析

  时间复杂度:O(n log n)   合并复杂度为n,递归过程的复杂度为log2n

  空间复杂度:O(n)             需要一个辅助数组

  稳定性:稳定。

  八大排序中其余两个nlogn复杂度的堆排序和快速排序是不稳定的,较普通排序更快的希尔排序也是不稳定的。本文所讲的归并排序却是稳定的,而且效率也很可观。

  本文个人编写,水平有限,如有错误,恳请指出,欢迎讨论分享

原文地址:https://www.cnblogs.com/wanghang-learning/p/9209321.html

时间: 2024-08-07 18:35:48

八大排序之归并排序的相关文章

八大排序算法原理以及Java实现(直接插入排序)

概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1.插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到

八大排序算法

转载:http://blog.csdn.net/hguisu/article/details/7776068 目录(?)[+] 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速

八大排序算法源码 + 耗时长度比较(看到好东西转下)

八大排序算法的排序时间长度的比较,测试数据10000000时部分结果如下 输入测试数据长度: 10000000数据初始化中...数据初始化完成!        堆排序用时:    8秒 499毫秒      快速排序用时:   22秒  35毫秒      归并排序用时:   34秒 473毫秒 另外五种排序本人并未等待结果,读者可自行测试 测试时请注意内存消耗,以免数据太大,内存不够,可自行测试单一算法以便增加可测试数据数目 #include <iostream> #include <

八大排序算法(JAVA实现)

概论: 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我整理的八大排序就是内部排序. 当数据较多时应该采用时间复杂度为o(nlog2n)的排序方法:快速排序.堆排序.归并排序 快速排序是这几种内部排序中最好的方法,想待排序的关键字是随机分布时,快速排序的平均时间最短. 直接插入排序: 思想 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个

数据结构与算法之——八大排序算法

附:关于这个主题,网上好的文章已经数不胜数,本篇是整合后的文章. 正文: 一.概述 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 本文所指八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 二.排序算法详述 1.

八大排序算法python实现(转)

一.概述   排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 二.算法实现   1.插入排序-直接插入排序(Straight Insertion Sort) 基

八大排序算法总结及C/C++实现

概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1. 插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到

[Data Structure] 八大排序算法

排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序算法体系结构图: 1. 直接插入排序(Straight Insertion Sort ) 基本思想:将待排序的无序数列看成是一个仅含有一个元素的有序数列和一个无序数列,将无序数列中的元素逐次插入到有序数列中,从而获得最终的有序数列. 算法流程: 1)初始时, a[0]自成一个有序区, 无序区为a[1

(转)详解八大排序算法

概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到