归并排序

本文详细介绍了归并排序的基本原理及其实现过程。首先解释了如何将两个已排序的子序列合并为一个有序序列,接着展示了如何通过递归地将整个序列拆分成更小的有序子序列来完成排序。文章还提供了完整的C++实现代码。

 

所谓归并(merging)是将链两个或两个以上的有序表合并成一个新的有序表。

先考虑一种特殊情形:

 

设线性表L[1:n]中的某段L[low:high]已经部分有序,即它的两个子表L[low:mid]与L[mid+1:high]已经有序,现要将这两个有序子表归并成一个有序子表L[low:high]。

实现上述两个子表的归并,基本做法如下:

(1)       开辟一个与线性表L同样大小的表空间A;

(2)       设置三个指针i,j,k,其初始状态分别指向两个有序子表的首部及表空间A中与L中需要进行排序段相对应空间的首部。即i=low, j=mid+1, k=0;

(3)       沿两个有序子表扫描:

若L[i]<L[j],则A[k]=L[i],且i与k的指针均加1;否则A[k]=L[j],且j与k的指针均加1。如此反复,直到有一个子表的指针已经直到末端为止(即子表内的元素已经取空)

(4)       将未取空的子表中的剩余元素依次放入表空间A中;

(5)       将A中的对应段复制到L中。

 

所谓归并排序,是指把一个长度为n的线性表看成由n个长度为1的有序表组成,然后反复进行两两归并,最后就得到程度为n的有序线性表。由于归并是两两进行的,因此也称为2-路归并排序。

归并排序的平均时间复杂度为O(nlogn),它是稳定的。

代码:

 

#include <iostream>
using namespace std;

void merge(double p[],int low, int mid, int high)
{
    int i=low;
    int j=mid+1;
    int k=0;

    double *p1;
    p1=(double*)malloc((high-low+1)*sizeof(double));

    while ((i<=mid)&&(j<=high))
    {
        if (p[i]<p[j])
        {
            p1[k]=p[i];
            i++;
            k++;
        } 
        else
        {
            p1[k]=p[j];
            j++;
            k++;
        }

    }

    while (i<=mid)  //将第1段余下部分复制到p1
    {
        p1[k]=p[i];
        i++;
        k++;
    }

    while (j<=high)  //将第2段余下部分复制到p1
    {
        p1[k]=p[j];
        j++;
        k++;
    }

    for (k=0,i=low;i<=high;k++,i++) //将p1复制回P中
    {
        p[i]=p1[k];
    }
    free(p1);
    return;
}


void merge_sort(double p[], int n)
{
    int m,k,j,low,mid,high;
    //double *a;
    //a=(double*)malloc(n*sizeof(double));
    m=1;
    while (m<n)
    {
        k=2*m;
        for (j=0;j<n;j=j+k)
        {
            low=j;
            high=j+k-1;
            mid=j+m-1;
            if(high>n-1)
                high=n-1;
            if(high>mid)
                merge(p,low,mid,high);
        }
        m=k;
    }
    return;
}

int main()
{
    double a[10];
    int i;

    cout<<"输入原始序列:"<<endl;
    for (i=0;i<10;i++)
    {
        cin>>a[i];
    }
    cout<<endl;

    merge_sort(a,10);
    cout<<"排序后:"<<endl;
    for (i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;

    return 0;

}

 

 

转载于:https://www.cnblogs.com/2007winter/archive/2012/06/08/2541822.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值