归并排序

归并排序的基本操作是合并两个已排序的表。因为两个表是已排序的,所以若将输出放到第三个表中则该算法可以通过对输入数据一趟排序来完成。基本的合并算法是取两个输入数组A和B、一个输出数组C以及三个计数器(Actr、Bctr、Cctr),他们的初始位置位于对应数组的初始端。A[Actr]和B[Bctr]中的较小者被复制到C[Cctr],相关的计数器向下移动一步。当两个输入表一个用完时,则将另一个表中的剩余部分拷贝到C中。具体递归算法用C++描述如下:


#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

/**
 * Internal method that merge two sorted halvas of a subarray.
 * data is an array of Comparable items.
 * tmpArray is an array to place the merged result.
 * leftPos is the left-most index of the subarray.
 * rightPos is the index of the start of the second half.
 * rightEnd is the right-most index of the subarray.
 */
template <class Comparable>
void merge(vector<Comparable> &data, vector<Comparable> &tmpArray, int leftPos, int rightPos, int rightEnd)
{
    int leftEnd = rightPos - 1;//the index of the start of the first half.
    int tmpPos = leftPos;      //the index of the start of the tmpArray.
    int numElements = rightEnd - leftPos + 1; //the number of the items

    //merge
    while(leftPos <= leftEnd && rightPos <= rightEnd)
    {
        if(data[leftPos] < data[rightEnd])
        {
            tmpArray[tmpPos++] = data[leftPos++];
        }
        else
        {
            tmpArray[tmpPos++] = data[rightPos++];
        }
    }

    if(leftPos > leftEnd)
    {
        while(rightPos <= rightEnd)
        {
            tmpArray[tmpPos++] = data[rightPos++];
        }
    }
    else
    {
        while(leftPos <= leftEnd)
        {
            tmpArray[tmpPos++] = data[leftPos++];
        }
    }

    //copy tmpArray back
    for(int i=0; i<tmpPos; ++i)
    {
        data[i] = tmpArray[i];
    }
}

/**
 * Internal method that makes recursive calls.
 * data is an array of Comparable items.
 * tmpArray if an array to place the merged result.
 * left is the start index of the subArray.
 * right is the end index of the subArray.
 */
template <class Comparable>
void mergeSort(vector<Comparable> &data, vector<Comparable> &tmpArray, int left, int right)
{
    if(left < right)
    {
        int center = (left+right) / 2;
        mergeSort(data, tmpArray, left, center);
        mergeSort(data, tmpArray, center+1, right);
        merge(data, tmpArray, left, center+1, right);
    }
}

/**
 * mergeSort algorithm.
 */
template <class Comparable>
void mergeSort(vector<Comparable> &data)
{
    vector<Comparable> tmpArray(data.size());
    mergeSort(data, tmpArray, 0, data.size()-1);
}

int main(void)
{
    int ary[] = {0, 1, 9, 2, 8, 4, 5, 3, 6, 7};
    vector<int> data(ary, ary+sizeof(ary)/sizeof(int));
    mergeSort(data);
    copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}

归并排序的分析:

归并排序是用于分析递归例程技巧的经典实例:必须给运行时间写出一个地推关系。假设N是2的幂,从而总可以将它分成相等的两部分。对于N=1,归并排序所用的时间是常数,我们将其记为1。否则,对于N个数归并排序的用时相等于完成两个大小为N/2的递归排序所用的时间再加上合并的时间,他是线性的。下述方程给出准确的表示:
                                    T(1) = 1
                                    T(N) = 2T(N/2)+N

这是一个标准的地推关系,求解后得到这样的公式:

                                     T(N) = NlogN+N = O(NlogN)


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值