常用排序算法之归并排序

归并排序

  • 基本思想

取两个输入数组A和B,一个输出数组C,以及三个计数器Aptr,Bptr,Cptr,计数器开始都被置于对应数组的开始端。A[Aptr]和B[Bptr]中的较小者被拷贝到C中的下一个位置,相关的计数器向前推进一步。当A和B俩个表中有一个用完时,则将另一个表中剩下的部分拷贝到C中。

归并排序是递归算法的很好的实例,也是经典的分治策略。将问题分解为一些较小的问题然后递归求解,治的阶段则将分阶段的解得的各个答案修补到一起。

我们将数组A中的1,13,24,26,2,15,27,38这8数用归并排序进行排序。

现将数组A一分为二,24,1,26,13为左组。27,15,38,2为右组,再格外使用一个临时数组C用来存放最终结果。

先将左组中的数据递归进行排序,再将右组中的数据递归进行排序,最后将俩组数据进行合并。

  • 程序实现

#include<iostream>
using namespace std;
void print(int a[], int n){  
    for(int j= 0; j<n; j++)
    {  
        cout<<a[j] <<" ";  
    }  
    cout<<endl;  
}  
void mergearray(int a[], int first, int mid, int last, int temp[])  
{  
    int i = first, j = mid + 1;  //俩个指针,i左边数组的指针。j右边数组的指针
    int m = mid,   n = last;  //m左边数组的边界,n右边数组的边界
    int k = 0;  
      
    while (i <= m && j <= n)  
    {  
        if (a[i] <= a[j])  //总是将每半边中较小的一个数赋值给temp。
            temp[k++] = a[i++];  
        else  
            temp[k++] = a[j++];  
    }  
      
    while (i <= m)  
        temp[k++] = a[i++];  
      
    while (j <= n)  
        temp[k++] = a[j++];  
      
    for (i = 0; i < k; i++)  
        a[first + i] = temp[i];  //重新将temp赋值给a
}  
void mergesort(int a[], int first, int last, int temp[])  
{  
    if (first < last)  
    {  
        int mid = (first + last) / 2;  
        mergesort(a, first, mid, temp);    //左边有序  
        mergesort(a, mid + 1, last, temp); //右边有序  
        mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
        print(a, 8);
    }  
}  
  
bool MergeSort(int a[], int n)  
{  
    int *p = new int[n];  
    if (p == NULL)  
        return false;  
    mergesort(a, 0, n - 1, p);  
    delete[] p;  
    return true;  
} 
int main()
{
    int a[8]={24,1,26,13,27,15,38,2};
    MergeSort(a, 8);
    system("pause");
}

  • 程序实现分析:

MergeSort(a, 8);将数组a中的8个数进行排序。

1:开始

mergesort(a, 0, 7, p); 第一个数是a[0],第二个数是a[7],mid为3,

first < last 

递归调用左边:mergesort(a, 0, 3, p);右边:mergesort(a, 4, 7, p);

2::mergesort(a, 0, 3, p);第一个数是a[0],第二个数是a[3],mid为1, 

first < last

递归调用左边:mergesort(a, 0, 1, p);右边:mergesort(a, 2, 3, p);

3::mergesort(a, 0, 1, p);第一个数是a[0],第二个数是a[1],mid为0, 

first < last

递归调用左边:mergesort(a, 0, 0, p);右边:mergesort(a, 1, 1, p);

4:左3:mergesort(a, 0, 0, p);第一个数是a[0],第二个数是a[0],mid为0, 

first = last,结束。

 右3:mergesort(a, 1, 1, p);第一个数是a[1],第二个数是a[1],mid为1, 

first = last,结束。

5:返回上一层开始进行合并,上一层first为0,last为1,mid为0,

依次类推,递归求解各个部分,最后再合并起来。

整个递归调用示意图如下图所示,递归调用最后一层first=last,结束递归调用返回上一层进行mergearray(a, first, mid, last, temp);将左右两个数组合并。


  • 时间复杂度为O(NlogN)归并排序很难用于主存排序,因为它在合并两个排序表时需要线性附加内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值