C++实现链表自底向上的归并排序

链表自底向上的归并排序基于C++中的list容器,基本思想和自底向上的数组归并排序在实质上没有区别,即分组两两归并,每一轮归并结束后分组大小扩大一倍。不熟悉自底向上归并排序的同学可以查阅相关资料,这里不再赘述

但需要注意的是,链表自底向上的归并排序针对list的特殊存储结构进行少许优化以加快归并速度,具体见以下代码

#include <iostream>
#include <list>
#include <random>
#include <vector>

using std::cout;
using std::list;
using std::shuffle;
using std::default_random_engine;
using std::vector;

template <typename T>
void listSort(list<T> &_list)
{
    if (_list.empty())
        return;

    size_t k = 1;
    while (true)
    {
        typename list<T>::iterator first = _list.begin();
        typename list<T>::iterator second = first;

        while (true)
        {
            size_t count = 1;
            do
            {
                ++count;
                ++second;

            } while (second != _list.end() && count <= k);

            if (second == _list.end())
            {
                if (first == _list.begin())
                    return;
                break;
            }

            count = 1;
            while (first != second && second != _list.end() && count <= k)
            {
                if (*first <= *second)
                {
                    ++first;
                }
                else
                {
                    T temp = *second;
                    second = _list.erase(second);
                    _list.insert(first, temp);
                    ++count;
                }
            }

            if (first == second)
            {
                do
                {
                    ++first;
                    ++count;
                } while (first != _list.end() && count <= k);

                if (first == _list.end())
                {
                    break;
                }
                second = first;
            }
            else
            {
                if (second == _list.end())
                {
                    break;
                }
                first = second;
            }
        }
        k = k << 1;
    }
}
int main()
{
    const size_t N = 2000;
    for (size_t j = 1; j <= N; ++j)
    {
        vector<size_t> sort_seq(j);
        for (size_t i = 0; i < sort_seq.size(); ++i)
        {
            sort_seq[i] = i + 1;
        }
        shuffle(sort_seq.begin(), sort_seq.end(), default_random_engine());
        list<size_t> test_obj;
        for (size_t i = 0; i < sort_seq.size(); ++i)
        {
            test_obj.push_back(sort_seq[i]);
        }

        cout << "排序前序列:" << std::endl;
        for (const size_t& run : test_obj)
        {
            cout << run << " ";
        }
        cout << std::endl;
        listSort(test_obj);
        size_t num = 1;
        for (list<size_t>::iterator run = test_obj.begin(); run != test_obj.end(); ++run)
        {
            if (*run != num)
            {
                cout << "排序结果错误!" << std::endl;
                return -1;
            }
            ++num;
        }
        cout << "排序结果正确" << std::endl;
        cout << "排序结果:" << std::endl;
        for (const size_t& run : test_obj)
        {
            cout << run << " ";
        }
        cout << std::endl;
    }

    return 0;
}

感兴趣的同学可尽情拷贝测试以上代码,但引用代码务必注明来源,以尊重作者的劳动成果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值