经典算法学习——归并排序

Posted 乞力马扎罗的雪CYF

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典算法学习——归并排序相关的知识,希望对你有一定的参考价值。

       归并排序算法采用的是分治算法,即把两个或两个以上的有序表合并成一个新的有序表的过程。首先把待排序的序列分成若干个子序列,每个子序列都是有序的,然后把有序子序列合并成整体有序序列,这个过程也称为2路归并。实现代码已经上传至: https://github.com/chenyufeng1991/MergeSort  。

       基本思想如下:将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。

      综上可知,归并排序其实要做两件事情:

(1)“分解”——将序列每次折半划分;

(2)“合并”——将划分后的序列段两两合并后排序;

那么如何进行合并呢?

       在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。这两个有序序列段分别为R[low,mid],R[mid+1,high]。先将它们合并到一个局部的暂存数组R2中,合并完成后再将R2复制到R中。R[low,mid]称为第一段,R[mid+1,high]称为第二段,每次从两个段中取出一个记录进行关键字的比较,将较小者放入R2中。最后将各段中余下的部分直接复制到R2中。经过这样,R2已经是一个有序的序列,再将其复制回R中,一次合并排序就完成了。代码如下:

//
//  main.c
//  MergeSort
//
//  Created by chenyufeng on 16/2/16.
//  Copyright © 2016年 chenyufengweb. All rights reserved.
//

#include <stdio.h>

void MergeSort(int *a,int begin,int end,int *temp);
void MergeArray(int *a,int begin,int mid,int end,int *temp);

int main(int argc, const char * argv[]) {

    int num[] = {2,5,9,3,6,1,0,7,4,8};
    int temp[10];
    MergeSort(num,0,9,temp);
    for(int i = 0;i < 10;i++){
        printf("%d ",num[i]);
    }
    printf("\\n");
    return 0;
}

//将有二个有序子数组a[begin...mid]和a[mid+1...end]合并;
void MergeArray(int *a,int begin,int mid,int end,int *temp){

    int i = begin,j = mid + 1;
    int m = mid,n = end;
    int k = 0;

    //开始合并两个数组;
    while(i <= m && j <= n){
        if(a[i] <= a[j]){
            temp[k++] = a[i++];
        }else{
            temp[k++] = a[j++];
        }
    }

    while(i <= m){
        temp[k++] = a[i++];
    }

    while(j <= n){
        temp[k++] = a[j++];
    }

    //把temp数组中的结果装回a数组
    for(i = 0;i < k;i++){
        a[begin + i] = temp[i];
    }
}

void MergeSort(int *a,int begin,int end,int *temp){
    if(begin < end){

        int mid = (begin + end) / 2;
        /**
         *  分别递归进行排序,也称为2-路归并;
         */
        MergeSort(a,begin,mid,temp);   //左边有序
        MergeSort(a,mid + 1,end,temp);   //右边有序
        MergeArray(a,begin,mid,end,temp); //将左右两边有序的数组合并
    }
}


     说明一下,归并排序的时间复杂度为O(N*logN),空间复杂度为O(1),是一种稳定的排序。





本文参考:http://www.cnblogs.com/jingmoxukong/p/4308823.html

http://blog.csdn.net/chenhuajie123/article/details/9296359

以上是关于经典算法学习——归并排序的主要内容,如果未能解决你的问题,请参考以下文章

九种经典排序算法详解(冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序,计数排序,桶排序,基数排序)

经典算法之归并排序——python和JS实现

经典排序算法---归并排序

经典排序算法之归并排序

十大经典排序算法总结(基数排序)

十大经典排序算法总结(桶排序)