【链表 归并排序】(C++ OOP | templateADP | 递归)

代码不长,值得注意的点很多。已经做了测试,可以拷下来在本地跑一下

code 2024/02/18:

//头文件
#include <functional>
#include <initializer_list>
#include <iostream>

//模板类
template <class Tp>
class list {


friend std::ostream& operator<< <Tp>(std::ostream&, const list<Tp>&);
//输出操作符重载友元


    struct Node {
        Tp           __value__ {};//值
        struct Node *__next__  {};//后继
    }  * const mono { new Node };
//节点定义,mono为空头结点


public:
//默认构造
    constexpr list(void) noexcept = default;

//批量插入,传参构造
    template <typename Up>
    inline list(std::initializer_list<Up> li) {
        for (auto v : li) insert(v);
    }

//析构,销毁链表
    ~list(void) noexcept{
        Node *curr { mono };
        while(curr){
            Node *next { curr->__next__ };
            delete curr;
            curr = next;
        }
    }

//头插入
    constexpr void insert(const Tp& v) {
        Node *o { new Node{ __value__ : v, __next__ : mono->__next__ } };
        mono->__next__ = o;
    }

//排序接口,模板传排序规则,默认为内建 <号
    template <typename Compare = std::less<Tp>>
    void sort(void) {
        auto& head { mono->__next__ };
        head = sort<Compare>(head, nullptr);
    }
private:
//递归DC
    template <typename Compare>
    Node *sort(Node *first, Node *last) {
//special judge
	    if (!first) return first;
        if (first->__next__ == last) {
            first->__next__ = nullptr;
            return first;
        }
//快慢指针找middle
        Node *slow { first };
        Node *fast { first };
        while (!(fast == last)) {
            slow = slow->__next__;
            fast = fast->__next__;
            if (!(fast == last))
                fast = fast->__next__;
        }
        Node *middle { slow };
//递归,合并
        return merge<Compare>(sort<Compare>(first, middle), sort<Compare>(middle, last));
    }
    
//合并有序链表
    template <typename Compare>
    Node *merge(Node *begin_v, Node *begin_u) {
        Node *dummy { new Node };
        Node *tgt   { dummy };
        Node *p     { begin_v };
        Node *q     { begin_u };
        while (p && q) {
            auto& cur {
                Compare{}(p->__value__, q->__value__)
                ? p : q };
            tgt->__next__ = cur;
            cur = cur->__next__;
            tgt = tgt->__next__;
        }
        if (p) tgt->__next__ = p;
        else if (q) tgt->__next__ = q;
        auto result { dummy->__next__ };
        delete dummy;
        return result;
    }
private:
//标准输出辅助函数
    void output(std::ostream& Os) const{
        Node *current { mono->__next__ };
        while(current) {
            Os << current->__value__ << ' ';
            current = current->__next__;
        }
    }
};
//模板类型推导指引
template <typename Up>
list(std::initializer_list<Up>)->list<Up>;

//重载输出操作符
template <typename Tp>
std::ostream& operator<<(std::ostream& Os, const list<Tp>& li){
    li.output(Os);
    return Os;
}

//测试程序
int main(void) {
    list li({1, 5, 2, 6, 3, 7, 3});
    std::cout << "initial:\n" << li << "\n\n";
    li.sort();
    std::cout << "asc:\n" << li << "\n\n";
    li.sort<std::greater<int>>();
    std::cout << "dec:\n" << li << "\n\n";
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值