归并排序算法

归并排序是建立在归并操作上的一种有效的排序算法。该算法是 分治法(Divide and Conquer)的一个非常典型的应用。

首先考虑如何将两个有序数列合并成一个有序序列?这个非常简单,只要比较两个数列的第一个数,谁小就先取谁,然后插入到新数列,再依次比较这两个数列剩余的数,谁小先把谁取出插入新数列,如果有数列为空,那直接将另一个数列的数据依次取出插入新数列即可。

//将有序数组a[]和b[]合并到c[]中
void MemeryArray(int a[], int n, int b[], int m, int c[])
{
	int i, j, k;

	i = j = k = 0;
	while (i < n && j < m)
	{
		if (a[i] < b[j])
			c[k++] = a[i++];
		else
			c[k++] = b[j++]; 
	}

	while (i < n)
		c[k++] = a[i++];

	while (j < m)
		c[k++] = b[j++];
}

可以看出合并有序数列的效率是比较高的,时间复杂度可以达到O(n)。

解决了上面的有序数列合并问题,再来看归并排序,基本思路就是将数组分成两组A,B,如果这两组组内的数据都是有序的,那么就可以很方便的将这两组数据进行排序。

如何让这两组数据分别有序呢?可以将A,B组两组再各自分成两组。依次类推,如下图所示,当分出来的小组只有一个数据时,其实这个小组的是数据已经达到了有序(一个数怎么都是有序的,难道不是吗!),然后再合并相邻的两个小组(有序数组的合并问题)就可以了。综述,归并排序问题可以分成两步进行,首先通过递归的分解数列成有序数列,再合并有序数列就解决了问题(显然分而治之思想)。

动画演示:


兑现代码:

#include<iostream>  
using namespace std;  

//打印数组
template<typename T>
void printArray(T arr[],int n)
{
    for (int i=0;i<n;i++)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;
}
//合并两个有序数组成一个有序数组
template<typename T>  
void mergearray(T a[], int first, int mid, int last, T temp[])    
{  //合并两数组 [first mid]  [mid last]  
    int i = first, j = mid + 1;    
    int m = mid,   n = last;    
    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++];    

    for (i = 0; i < k; i++)    
        a[first + i] = temp[i];    
}    

template<typename T>  
void mergesort(T a[], int first, int last, T 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); //再将两个有序数列合并    
    }    
}    

template<typename T>  
bool MergeSort(T a[], int n)    
{    
    T *p = new T[n];    
    if (p == NULL)    
        return false;    
    mergesort(a, 0, n - 1, p);    
    delete[] p;    
    return true;    
} 

int main()  
{  
    int b[]={2,4,7,5,8,1,3,6};  
    char s[] = {'e','f','a','h','b'};  

    MergeSort(b,8);  
    MergeSort<char>(s,5);  
    printArray<char>(s,5);
    printArray<int>(b,8);  
    system("pause");  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值