设为首页 加入收藏

TOP

归并排序(MergeSort)(三)
2015-07-20 17:25:10 来源: 作者: 【 】 浏览:8
Tags:归并 排序 MergeSort
间:
#define MID(i) (i >> 1) /// i / 2
#define NEXT_GAP(i) (i <<= 1)    ///下一个步长

int* helper;    ///辅助数组

/**********************************************
    函数:优化版归并函数
    说明:合并有序区间[low, mid)和[mid, high)
          right为右区间的遍历指针
          helper为局部变量覆盖全局声明
          这样做是为了减少代码行数
    时间复杂度:O(high - low)
**********************************************/
void merge(int* low, int* mid, int* high, int* right, int* helper)
{
    ///收缩左边界,不再考虑左区间原本位于正确位置的元素
    while(*low <= *right)  if(++low >= mid)  return;  ///如果左区间的元素全部在正确位置,那么右区间也是如此,直接返回
    int* left = low;    ///设置左区间遍历指针
    *(helper++) = *(right++);   ///别浪费上面循环失败的比较结果。。。
    if(right >= high) ///右区间空了
        while(left < mid) *(helper++) = *(left++); ///把左区间剩下的复制过去
    else while(true)
        {
            if(*left <= *right)  ///相等时下标小的优先,使得算法稳定
            {
                *(helper++) = *(left++);
                if(left >= mid) break; ///左区间扫描完直接跳出外层循环,此时右区间剩下来的元素本来就处于正确位置
            }
            else
            {
                *(helper++) = *(right++);
                if(right >= high) ///右区间空了
                {
                    while(left < mid) *(helper++) = *(left++); ///把左区间剩下的复制过去
                    break;  ///跳出外层循环
                }
            }
        }
    while(right > low) *(--right) = *(--helper);   ///再复制回来,不过要跳过右区间剩下的元素
}

/************************************************
    函数:自底向上版归并排序
    说明:对区间[low, low + range)范围的数据排序
    时间复杂度:O(nlgn)
************************************************/
void mergeSortRoutine(int* low, int* high, int range)
{
    for(int gap = 2; MID(gap) < range; NEXT_GAP(gap))
        for(int* right = low + gap, * mid = low + MID(gap); mid < high; right += gap, mid += gap)
            merge(right - gap, mid, right > high ? high : right, mid, helper);
}

/****************************************
    函数:归并排序“外壳”
****************************************/
void mergeSort(int* low, int* high)
{
    helper = new int[high - low];   ///辅助数组最多也就存输入的元素数
    if(helper != nullptr)
    {
        mergeSortRoutine(low, high, high - low);
        delete[] helper;    ///释放内存
    }
    else return;    ///空间不足,没法启动归并排序
}
不过不知道为什么在我电脑上递归版反而更快,真是奇怪。

后记

如果内容有误或有什么提议请在下面评论,谢谢。

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++算法之 判断是否为平衡二叉树 .. 下一篇C++学习:关于“std::vector(Type..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)
·MySQL下载与安装教程 (2025-12-26 13:21:26)
·Linux_百度百科 (2025-12-26 12:51:52)
·Shell 流程控制 | 菜 (2025-12-26 12:51:49)