Non-recursive merge sort with two nested loops - how?

前端 未结 4 1458
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 12:24

First question here, and yes this is a homework question. We are tasked with performing merge sort on an array (which I am familiar with), but in a way I am unsure of how to do.

4条回答
  •  逝去的感伤
    2021-02-04 12:36

    Here's my lazy, iterative/bottom-up merge-sort implementation that uses std::merge:

    template
    OutIt mergesort(InIt begin, InIt const end, OutIt o /* auxiliary buffer */)
    {
        ptrdiff_t j;
        for (j = 0; begin != end; ++begin, ++j)
        {
            for (ptrdiff_t n = 1; n <= j && j % (n * 2) == 0; n *= 2)
            {
                o = std::merge(o - n * 2, o - n, o - n, o, begin - n * 2);
                o = std::swap_ranges(begin - n * 2, begin, o - n * 2);
            }
            *o = *begin;
            ++o;
        }
        --j;
        for (ptrdiff_t m = 1, n = 1; n <= j; n *= 2)
        {
            if (j & n)
            {
                o = std::merge(o - (m + n), o - m, o - m, o, o - (m + n));
                o = std::swap_ranges(begin - (m + n), begin, o - (m + n));
                m += n;
            }
        }
        return o;
    }
    

    Here's an in-place version that uses std::inplace_merge:

    template
    InIt inplace_mergesort(InIt begin, InIt const end)
    {
        ptrdiff_t j;
        for (j = 0; begin != end; ++begin, ++j)
        {
            for (ptrdiff_t n = 1; n <= j && j % (n * 2) == 0; n *= 2)
            { std::inplace_merge(begin - n * 2, begin - n, begin); }
        }
        --j;
        for (ptrdiff_t m = 1, n = 1; n <= j; n *= 2)
        {
            if (j & n)
            {
                std::inplace_merge(begin - (m + n), begin - m, begin);
                m += n;
            }
        }
        return begin;
    }
    

提交回复
热议问题