zoukankan      html  css  js  c++  java
  • 经典算法学习——归并排序

           归并排序算法採用的是分治算法,即把两个或两个以上的有序表合并成一个新的有序表的过程。首先把待排序的序列分成若干个子序列,每一个子序列都是有序的,然后把有序子序列合并成总体有序序列。这个过程也称为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]称为第二段,每次从两个段中取出一个记录进行keyword的比較,将较小者放入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("
    ");
        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

  • 相关阅读:
    20145213《Java程序设计》第二周学习总结
    20145213《Java程序设计》第一周学习总结
    对于老师问卷调查中若干问题的回答
    问卷调查
    关于矩阵的分解的专题讨论
    关于合同变换的专题讨论
    关于初等变换的专题讨论
    关于矩阵的迹的专题讨论
    关于矩阵的秩的专题讨论
    关于含参变量反常积分一致收敛的专题讨论
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7116742.html
Copyright © 2011-2022 走看看