c/c++常用算法(12) -- 基本排序算法(归并排序)

来源:互联网 发布:2017年海外代购数据 编辑:程序博客网 时间:2024/05/01 19:34

归并排序

归并(Merging) :是指将两个或两个以上的有序序列合并成一个有序序列。若采用线性表(无论是那种存储结构)易于实现,其时间复杂度为O(m+n)。


       归并思想实例:两堆扑克牌,都已从小到大排好序,要将两堆合并为一堆且要求从小到大排序

              ◆ 将两堆最上面的抽出(设为C1,C2)比较大小,将小者置于一边作为新的一堆(不妨设C1<C2);再从第一堆中抽出一张继续与C2进行比较,将较小的放置在新堆的最下面;

              ◆重复上述过程,直到某一堆已抽完,然然后将剩下一堆中的所有牌转移到新堆中。


1   排序思想


       ①  初始时,将每个记录看成一个单独的有序序列,则n个待排序记录就是n个长度为1的有序子序列;

       ②  对所有有序子序列进行两两归并,得到én/2ù个长度为2或1的有序子序列——一趟归并

       ③  重复②,直到得到长度为n的有序序列为止。

              上述排序过程中,子序列总是两两归并,称为2-路归并排序。其核心是如何将相邻的两个子序列归并成一个子序列。设相邻的两个子序列分别为:

                     {R[k], R[k+1], …,R[m]}和{R[m+1],R[m+2],…,R[h]},将它们归并为一个有序的子序列:

                    {DR[l],DR[l+1],…,DR[m], DR[m+1], …,DR[h] }

2.举例




3.实现代码:

////  main.cpp//  CHelloWorld////  Created by IDEA-MAC03 on 13-12-16.//  Copyright (c) 2013年 IDEA-MAC03. All rights reserved.//#include <iostream>#include <time.h>#define SIZE 15//完成一遍合并的函数void MergeOne(int a[],int b[],int n,int len){    int i,j,k,s,e;        s = 0;    while (s + len < n)    {        e = s+ 2*len -1;        if (e >= n)        {            e = n-1;        }        //相邻有序合并        k = s;        i = s;        j = s + len;        while (i < s+len && j<= e)        {            if (a[i]<= a[j])            {                b[k++] = a[i++];            }            else            {                b[k++] = a[j++];            }        }        while (i < s+len)        {            b[k++] = a[i++];        }                while (j<= e)        {            b[k++] = a[j++];        }                s = e + 1;    }    if (s<n)            //将剩余的一个有序段从数组a中复制到数组b中    {        for (; s<n; s++)        {            b[s] = a[s];        }    }}//合并排序void MergeSort(int a[],int n){    int *p;    int h,count,len,f;        count = 0;                              //排序步骤    len =1;                                 //有序序列的升序    f = 0;                                  //变量f作标志    if (!(p=(int *)malloc(sizeof(int)*n)))  //分配内存空间    {        printf("内存分配失败!\n");        exit(0);    }        while (len < n)    {        if (f == 1)     //交替在a和p之间合并        {            MergeOne(p, a, n, len); //p合并到a        }        else        {            MergeOne(a, p, n, len); //a合并到p        }        len = len *2;        f = 1-f;                count++;        printf("第%d步排序结果:",count);        for (h = 0; h < SIZE; h++)        {            printf(" %d",a[h]);        }        printf("\n");    }    if (f)    {        for (h = 0; h < n; h++)        {            a[h] = p[h];        }    }    free(p);    }int main(int argc, const char * argv[]){    int shuzu[SIZE],i;        srand(time(NULL));    for (i=0; i<SIZE; i++)    {        shuzu[i] = rand() % 100;    }    printf("排序前的数组为:\n");        for (i=0; i<SIZE; i++)    {        printf(" %d",shuzu[i]);    }    printf("\n");    MergeSort(shuzu,SIZE);    printf("排序后的数组为:\n");    for (i=0; i<SIZE; i++)    {        printf(" %d",shuzu[i]);    }     printf("\n");    // std::cout << "Hello, World!\n";    return 0;}

运行结果:


       


参考书籍:《C/C++常用算法手册》  《数据结构-清华大学严蔚敏》

0 0