优化的归并排序

优化的归并排序:设定一个阈值(THRESHOLD),对大于该阀值的区间进行归并排序,反之用插入排序。在合并两个已拍好的区间时,通过倒置后面一个区间,比较两个下标来判断拷贝结束。

/****************** 优化的归并排序 ******************/
const int THRESHOLD = 28;
template <class Record>
void InsertSort (Record Array[], int n)
{
    // 直接插入排序,Array[]为待排序数组,n为数组长度
    Record TempRecord;						// 临时变量
    for (int i=1; i<n; i++)   					// 依次插入第i个记录
    {
        TempRecord=Array[i];
        int j = i-1;
        //从i开始往前寻找记录i的正确位置
        while (j >= 0 && TempRecord < Array[j])
        {
            Array[j+1] = Array[j];  // 将那些大于等于记录i的记录后移
            j = j - 1;
        }
        Array[j+1] = TempRecord;    // 此时j后面就是记录i的正确位置,回填
    }
}

template <class Record>
void ModMerge(Record Array[],Record TempArray[],int left,int right,int middle)  //归并过程
{
    int index1,index2;							    // 两个子序列的起始位置
    int i,j,k ;
    for (i=left; i<=middle; i++)			        // 复制左边的子序列
        TempArray[i] = Array[i];
    for (j=1; j<=right-middle; j++)		            // 复制右边的子序列,但顺序颠倒过来
        TempArray[right-j+1] = Array[j+middle];
    // 开始归并,取较小者插入合并数组中
    for (index1=left, index2=right, k=left;  k<=right;  k++)
        if (TempArray[index1] <= TempArray[index2])	// 为保证稳定性,相等时左边优先
            Array[k] = TempArray[index1++];
        else  Array[k] = TempArray[index2--];
}

template <class Record>
void ModMergeSort(Record Array[], Record TempArray[], int left, int right)
{
//	if (right <= left)	return;						// 如果只含有一个元素,直接返回
    if (right-left+1 > THRESHOLD)   				//如果序列长度大于阈值(16最佳),跳出递归
    {
        int middle=(left+right)/2;					    // 从中间划分为两个子序列
        ModMergeSort(Array, TempArray ,left,middle);    // 对左边一半进行递归
        ModMergeSort(Array, TempArray ,middle+1,right);	// 对右边一半进行递归
        ModMerge(Array, TempArray ,left,right,middle);	// 进行归并
    }
    else  InsertSort(&Array[left],right-left+1);        // 若长度小于等于阈值,采用直接插入排序
}

template <class Record>
void sort(Record* array, int n)
{
    static Record* temp = NULL;
    if (temp == NULL) temp = new Record[n];				// 申请辅助数组
    ModMergeSort(array, temp, 0, n-1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值