【链表 快速排序】

链表不适合写快速排序,但是也可以写

#include <utility>
#include <initializer_list>
#include <ranges>
#include <type_traits>
#include <functional>
#include <iostream>

template< class From, class To >
concept convertible_to =
    std::is_convertible_v<From, To> &&
    requires {
        static_cast<To>(std::declval<From>());
    };
//插入过程中保证assignable and construtible
//定义概念约束

template <class Tp> requires convertible_to<Tp&, Tp>
class list{
friend std::ostream& operator<< <Tp>(std::ostream&, const list<Tp>&);
//输出运算符重载函数友元
	struct Node{
	 Tp           __value__;
	 struct Node *__next__ {nullptr};
	 constexpr ~Node(void) noexcept { std::exchange(__next__, nullptr); }
	} *dummy{ new Node };
//节点定义,虚拟头节点(哑元)
public:
	constexpr list(void) noexcept = default;
	template <typename Up>
//batch insertive construct(头插,注意倒序插入)
	constexpr list(std::initializer_list<Up> li) noexcept{
		for(auto& element : li | std::views::reverse ) insert(element);
	}
//头插
	void insert(const Tp& value) noexcept{
		Node *E { new Node{ __value__ : value, __next__ : dummy->__next__ } };
		dummy->__next__ = E;
	}
//sort透明接口
	template <typename Compare = std::less<Tp>>
	void sort(void){
		auto& head = dummy->__next__;
		head = sort<Compare>(head, nullptr);
	}
private:
//递归
	template <typename Compare>
	Node *sort(Node *first, Node *last){
//special judge 递归出口
	    if (!first || first->__next__ == last)
	        return first;

	    Node* slow { first };
	    Node* fast { first };
//快慢指针找中点
	    while (!(fast == last)) {
	        slow = slow->__next__;
	        fast = fast->__next__;

	        if (!(fast == last))
	            fast = fast->__next__;
	    }

	    Node* pivot = slow;
//划分
	    first = partition<Compare>(first, last, pivot->__value__);
//向下递归
	    first = sort<Compare>(first, pivot);
	    pivot->__next__ = sort<Compare>(pivot->__next__, last);

	    return first;
	}
//划分
	template <typename Compare>
	Node *partition(Node *first, Node *last, Tp const& pivot){
		Node *dummy_smaller { new Node };
		Node *dummy_larger  { new Node };
		Node *smaller { dummy_smaller };
		Node *larger  { dummy_larger };
		while(!(first == last)){
			if(Compare{}(first->__value__, pivot))
				smaller = (smaller->__next__ = first);
			else
				larger = (larger->__next__ = first);
			first = first->__next__;
		}
		larger->__next__ = last;
		smaller->__next__ = dummy_larger->__next__;
		Node *buffer { dummy_smaller->__next__ };
		delete dummy_smaller;
		delete dummy_larger;
		return buffer;
	}
private:
//输出辅助函数
	void output(std::ostream& Os) const{
		Node *current { dummy->__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;
}

评论 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、付费专栏及课程。

余额充值