码迷,mamicode.com
首页 > 编程语言 > 详细

归并排序

时间:2014-12-08 23:04:54      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:归并排序

归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。

算法描述

归并操作的过程如下:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤3直到某一指针到达序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾
最差时间复杂度 bubuko.com,布布扣
最优时间复杂度 bubuko.com,布布扣
平均时间复杂度 bubuko.com,布布扣
最差空间复杂度 bubuko.com,布布扣

自顶向下的归并排序(递归):

#include<iostream>
using namespace std;
class MergeSort
{
public:
    void merge(int a[],int l,int mid,int h)
        {
            int i=l;
            int j=mid+1;
            for(int k=l;k<=h;++k)
                aux[k]=a[k];
            for(int k=l;k<=h;++k)
            {
                if(i>mid)a[k]=aux[j++];//左半边元素用尽
                else if(j>h)a[k]=aux[i++];//右半边元素用尽
                else if(aux[i]<aux[j])a[k]=aux[i++];//左半边元素小于右半边元素
                else a[k]=aux[j++];//左半边元素大于右半边元素
            }
        }
    void sort(int a[],int l,int h)
        {
            if(h<=l)return ;
            int mid=l+(h-l)/2;
            sort(a,l,mid);
            sort(a,mid+1,h);
            merge(a,l,mid,h);
        }
    void sort()
        {
            sort(a,0,n-1);
        }
    MergeSort(int *a,int n)
        {
            this->n=n;
            this->a=a;
            aux=new int(n);
        }
    ~MergeSort(){
        free(aux);
    }
private:
    int *aux;
    int n;
    int *a;
};

int main(int argc, char *argv[])
{
    int a[]={4,5,6,7,1,2,3,0};
    MergeSort m(8);
    m.sort(a);
    for(int i=0;i<sizeof(a)/sizeof(int);++i)
        printf("%d\n",a[i]);
    return 0;
}

经验:使用插入排序处理小规模的子数组(比如长度小于15),一般可以将归并排序的运行时间缩短10%~15%

自底向上的归并排序(迭代):

class MergeSort2{
public :
    MergeSort2(int a[],int n){
        this->n=n;
        this->a=a;
        aux=new int(n);
    }
    ~MergeSort2(){free(aux);}
    inline int min(int a,int b)
        {return a<b?a:b;}
    void sort()
        {
            for(int sz=1;sz<n;sz=sz+sz)
                for(int l=0;l<n-sz;l+=sz+sz)
                    merge(a,l,l+sz-1,min(l+sz+sz-1,n-1));
        }
    void merge(int a[],int l,int mid,int h)
        {
            int i=l;
            int j=mid+1;
            for(int k=l;k<=h;++k)
                aux[k]=a[k];
            for(int k=l;k<=h;++k)
            {
                if(i>mid)a[k]=aux[j++];
                else if(j>h)a[k]=aux[i++];
                else if(aux[i]<aux[j])a[k]=aux[i++];
                else a[k]=aux[j++];
            }
        }
private:
    int n;
    int *aux;
    int *a;
};

自底向上的归并排序比较适合用链表组织的数据。想象一下将链表先按大小为1的子链表进行排序,然后是大小为2的子链表,然后是大小为4的子链表等。这种方法只需要重新组织链表链接就能将链表原地排序(不需要创建任何新的链表结点)。

归并排序

标签:归并排序

原文地址:http://blog.csdn.net/wdkirchhoff/article/details/41810861

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!