408【数据结构】单链表_模板类_源码模块

实现源码

  • 源码模块

my_check.hpp

#ifndef MY_CHECK_HPP
#define MY_CHECK_HPP

#include<stdexcept>
#include<iostream>

#include"my_config.h"

#if _GLIBCXX_VER
#define CHECK(x, y) check_pointer_range::check(x, y)
#else
#define CHECK(x, y)
#endif

#if _GLIBCXX_VER
#define CHECK_N_PTR(x) check_nullptr::check(x)
#else
#define CHECK_N_PTR(x)
#endif

#if _WIN32
#define DEBUG() std::cerr << __LINE__ << "\n" 
#else
#define DEBUG()
#endif // _WIN32

struct check_pointer_range {
	template<typename T>
	static constexpr void check(T* x, T* y) {
		if(!x || !(--y))
			std::cerr << "The pointer is nullptr" << "\n";
	}
};

struct check_nullptr {
	template<typename T>
	static constexpr void check(T* x) {
		if(!x)
			std::cerr << "The pointer is nullptr" << "\n";
	}
};

#endif // !MY_CHECK_HPP

link_list.hpp

#ifndef LINK_LIST_HPP
#define LINK_LIST_HPP

#include<initializer_list>
#include<type_traits>

#include"my_check.hpp"

template<class T>
struct Node {
	Node() : data(T{}), next(nullptr) {}
	T data;
	Node* next;
};

template<class T>
class LinkList {
public:
	using size_type = std::int64_t;
	using value_type = T;
	using reference = T&;
	using const_reference = const T&;
	using const_pointer_type = const Node<T>*;
	using pointer_type = Node<T>*;

public:
	LinkList() : _head(new Node<value_type>), _ret_ptr(nullptr) {}

	explicit LinkList(std::initializer_list<T> li) : _head(new Node<value_type>), _ret_ptr(nullptr) {
		for(auto it = li.begin(); it != li.end(); ++it)
			this->push(*it);
	}

	LinkList(const LinkList& x) : _head(new Node<value_type>), _ret_ptr(nullptr) {
		this->copyElement(x.getHeadPtr());
	}

	~LinkList() {
		if(_ret_ptr)
			_ret_ptr = nullptr;
		if(_head) {
			while(_head->next) {
				this->pop();
			}
			delete _head;
			_head = nullptr;
		}
	}

public:
	template<typename U,
		typename std::enable_if<std::is_same<U, value_type>::value, int>::type = 0>
	void push(U val) {
		Node<U>* tmp = new Node<T>;
		tmp->data = val;
		tmp->next = _head->next;
		_head->next = tmp;
	}

	void pop() {
		this->checkNullContainer("the list isn't elements");
		pointer_type del = _head->next;
		_head->next = del->next;
		delete del;
		del = nullptr;
	}


	/// @brief 删除 @c p 指向的元素
	/// @return 返回当前删除元素的下一个指针
	pointer_type erease(pointer_type p) {
		this->checkNullContainer("the list isn't elements");
		CHECK_N_PTR(p->next);
		CHECK_N_PTR(p);
		pointer_type del_p = p->next;
		//swap next node's value
		::swap(p->data, del_p->data);
		p->next = del_p->next;
		delete del_p;
		del_p = nullptr;
		return p;
	}

	/// @brief 删除 @a beg 到 @a end 范围内的数据
	/// @return end's pointer
	pointer_type erease(pointer_type beg, pointer_type end) {
		this->checkNullContainer("the list isn't elements");
		CHECK_N_PTR(beg);
		while(beg->next != end)
			beg = this->erease(beg);
		end = this->erease(beg);
		return end;
	}

	reference front() {
		this->checkNullContainer("the list isn't elements");
		return _head->next->data;
	}

	const_reference front() const {
		this->checkNullContainer("the list isn't elements");
		return _head->next->data;
	}

	value_type back(size_type k) const {
		this->checkNullContainer("The link list is empty");
		pointer_type p = nullptr;
		value_type tmp {};
		size_type n = this->size();
		if(k > n || k <= 0)
			return INT_MIN;
		n = n - k + 1;
		p = _head;
		for(; n > 0; --n)
			p = p->next;
		tmp = p->data;
		return tmp;
	}

	/// @brief 返回尾部第 @b k 个元素的指针
	/// @return pointer
	pointer_type backPtr(size_type k) {
		this->checkNullContainer("The link list is empty");
		_ret_ptr = nullptr;
		size_type n = this->size();
		if(k > n)
			return nullptr;
		n = n - k + 1;
		_ret_ptr = _head;
		for(; n > 0; --n)
			_ret_ptr = _ret_ptr->next;
		return _ret_ptr;
	}

	bool empty() const {
		return !_head->next;
	}

	size_type size() const {
		size_type count{};
		pointer_type p = _head->next;
		for(; p; p = p->next, ++count);
		return count;
	}

	/// @brief reverse range(_head, ...)
	void reverse() {
		this->checkNullContainer("The link list is empty");
		this->reverse(_head);
	}

	/// @brief reverse range[beg, ...)
	template<typename U,
		typename std::enable_if<std::is_same<value_type, U>::value, int>::type = 0>
	void reverse(Node<U>* beg) {
		CHECK_N_PTR(beg);
		Node<U>* prev(beg->next), * curr(nullptr);
		while(prev->next) {
			curr = prev->next;
			prev->next = curr->next;
			curr->next = beg->next;
			beg->next = curr;
		}
	}

	//reverse range[beg->next, end)
	template<typename U,
		typename std::enable_if<std::is_same<value_type, U>::value, int>::type = 0>
	void reverse(Node<U>* beg, Node<U>* end) {
		CHECK_N_PTR(beg);
		Node<U>* prev(beg->next), * curr(nullptr);
		while(prev->next != end) {
			curr = prev->next;
			prev->next = curr->next;
			curr->next = beg->next;
			beg->next = curr;
		}
	}

	/// @brief 查找 @a val
	/// @return 所查元素的指针
	pointer_type find(value_type val) {
		_ret_ptr = _head->next;
		while(_ret_ptr) {
			if(_ret_ptr->data == val)
				break;
			_ret_ptr = _ret_ptr->next;
		}
		if(_ret_ptr)
			return _ret_ptr;
		else
			return nullptr;
	}

	/// @brief select sort
	template<typename Compare = std::less<T>>
	void sort() {
		pointer_type prev = _head, curr(prev->next), cir(curr->next);
		while(curr) {
			while(cir) {
				if(Compare()(cir->data, curr->data))
					::swap(cir->data, curr->data);
				cir = cir->next;
			}
			prev = curr;
			curr = curr->next;
			if(curr)
				cir = curr->next;
		}
	}

	pointer_type headNode() {
		return _head;
	}

	const_pointer_type headNode() const {
		return _head;
	}

	pointer_type midPtr() {
		pointer_type slow(_head->next), fast(slow);
		_ret_ptr = nullptr;
		while(fast) {
			slow = slow->next;
			fast = fast->next->next;
			if(!fast || !fast->next)
				break;
		}
		if(slow)
			_ret_ptr = slow;
		return _ret_ptr;
	}

	/// @brief 交换头结点
	template<typename U,
		typename std::enable_if<std::is_same<U, value_type>::value, int>::type = 0>
	void swap(Node<U>* x) noexcept {
		pointer_type tmp = _head->next;
		_head->next = x->next;
		x->next = tmp;
		tmp = nullptr;
	}

	/// @brief 链接到其他单链表的结点
	/// @param x 其他单链表的结点
	template<typename U,
			typename std::enable_if<std::is_same<U, value_type>::value, int>::type = 0>
	void link(Node<U>* x) {
		pointer_type p = _head;
		while(p->next)
			p = p->next;
		p->next = x;
	}

private:
	void check(const char* msg) const {
		if(!_head->next)
			throw std::out_of_range(msg);
	}

	void checkNullContainer(const char* msg) const {
		try {
			this->check(msg);
		} catch(const std::exception& exc) {
			exc.what();
		}
	}

	template<typename U,
		typename std::enable_if<std::is_same<U, value_type>::value, int>::type = 0>
	void copyElement(Node<U>* x) {
		if(x) {
			x = x->next;
			while(x) {
				this->push(x->data);
				x = x->next;
			}
		}
	}

private:
	pointer_type _head;
	pointer_type _ret_ptr;
};

//algorithm

template<class T>
using pointer_type = Node<T>*;

template<class T>
using const_pointer_type = const Node<T>*;

template<typename T>
void swap(LinkList<T>& x, LinkList<T>& y) {
	x.swap(y.getHeadPtr());
}

#endif // !LINK_LIST_HPP
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值