#include"LinkedList.h" #include #include #include #include #ifndef __LinkedList_CPP__ #define __LinkedList_CPP__ templatetemplate LinkedListNode::LinkedListNode(T2&& data) : data(std::forward(data)), next(nullptr), last(nullptr) {} template LinkedListNode::LinkedListNode(const LinkedListNode& d) : data(d.data), last(nullptr), next(nullptr) {} template LinkedListNode& LinkedListNode::operator=(const LinkedListNode& d) { data = d.data; last = nullptr; next = nullptr; return *this; } template inline LinkedListNode* LinkedListNode::getNext() const { return next; } template inline LinkedListNode* LinkedListNode::getLast() const { return last; } template LinkedList::LinkedList() { end = head = nullptr; total = 0; } template LinkedList::~LinkedList() { clear(); } template LinkedList::LinkedList(LinkedList&& data) noexcept { if (&data == this)return; this->total = data.total; this->head = data.head; this->end = data.end; data.total = 0; data.head = nullptr; data.end = nullptr; } template LinkedList& LinkedList::operator=(LinkedList&& data) noexcept { if (this == &data)return *this; this->clear(); total = data.total; head = data.head; end = data.end; data.total = 0; data.head = nullptr; data.end = nullptr; return *this; } template LinkedList::LinkedList(const LinkedList& data) { if (&data == this)return; end = head = nullptr; total = 0; for (auto head = data.head; head; head = head->next) { add(head->data); } } template LinkedList& LinkedList::operator=(const LinkedList& data) { if (&data == this)return *this; this->clear(); end = head = nullptr; total = 0; for (auto head = data.head; head; head = head->next) { add(head->data); } return *this; } template inline bool LinkedList::isEmpty() const{ return !total; } template inline int LinkedList::size() const{ return total; } template void LinkedList::clear() { while (head) { remove(head); } } template template inline void LinkedList::add(T2&& data) { add(end,std::forward(data)); } template template void LinkedList::add(LinkedListNode* node, T2&& data) { if (total == INT_MAX)throw std::overflow_error("LinkedList over flow error."); if (!head) { end = head = new LinkedListNode(std::forward(data)); if (!head)return; head->next = head->last = nullptr; } else { LinkedListNode* temp = new LinkedListNode(std::forward(data)); if (!temp)return; temp->last = node; temp->next = node->next; node->next = temp; if(node==end) end = temp; } ++total; } template template void LinkedList::addFirst(T2&& data) { if (total == INT_MAX)throw std::overflow_error("LinkedList over flow error."); if (!head) { end = head = new LinkedListNode(std::forward(data)); if (!head)return; head->next = head->last = nullptr; } else { LinkedListNode* temp = new LinkedListNode(std::forward(data)); if (!temp)return; temp->last = nullptr; temp->next = head; head->last = temp; head = temp; } ++total; } template inline void LinkedList::addAll(const LinkedList &list) { addAll(end, list); } template void LinkedList::addAll(LinkedListNode* node,const LinkedList &list) { if (!head) { this->operator=(list); } else { auto temp = node; for (auto i = list.getHead(); i; i=i->getNext()) { add(temp, i->data); temp = temp->next; } } } template T& LinkedList::get(const int id) { if (id >= total||id<0)throw std::out_of_range("LinkedList out of range."); auto h = head; for (int i = 0; i < id; ++i) { h = h->next; } return h->data; } template const T& LinkedList::get(const int id) const { if (id >= total||id<0)throw std::out_of_range("LinkedList out of range."); auto h = head; for (int i = 0; i < id; ++i) { h = h->next; } return h->data; } template T& LinkedList::operator[](int i) { return get(i); } template T LinkedList::operator[](int i) const { return get(i); } template inline LinkedListNode* LinkedList::getHead() { return head; } template inline const LinkedListNode* LinkedList::getHead() const { return head; } template inline LinkedListNode* LinkedList::getEnd() { return end; } template inline const LinkedListNode* LinkedList::getEnd() const { return end; } template void LinkedList::remove(LinkedListNode* node) { if (node == head) { head = head->next; } if (node == end) { end = end->last; } if (node->last) { node->last->next = node->next; } if (node->next) { node->next->last = node->last; } --total; delete node; } template void LinkedList::remove(const int id) { if (id >= total||id<0)throw std::out_of_range("LinkedList out of range."); auto h = head; for (int i = 0; i < id; ++i) { h = h->next; } if (h == head) { head = head->next; } if (h->last) { h->last->next = h->next; } if (h->next) { h->next->last = h->last; } --total; delete h; } template void LinkedList::sort(const std::function &cmp) { for (auto i = head; i; i = i->next) { auto temp = i; for (auto j = i; j; j = j->next) { if (!cmp(temp->data, j->data))temp = j; } if (temp == i)continue; if (i == head)head = temp; else if (temp == head)head = i; if (i == end)end = temp; else if (temp == end)end = i; if (temp->next == i) { if(temp->last)temp->last->next = i; if(i->next)i->next->last = temp; temp->next = i->next; i->last = temp->last; temp->last = i; i->next = temp; } else if(i->next==temp){ if(i->last)i->last->next = temp; if(temp->next)temp->next->last = i; i->next = temp->next; temp->last = i->last; i->last = temp; temp->next = i; } else { //std::swap(i->data, temp->data); if (i->last)i->last->next = temp; if (i->next)i->next->last = temp; if (temp->last)temp->last->next = i; if (temp->next)temp->next->last = i; std::swap(temp->last, i->last); std::swap(temp->next, i->next); } i = temp; } } template T& LinkedList::search(const std::function& cmp) { for (auto i = head; i; i = i->next) { if (cmp(i->data))return i->data; } throw std::out_of_range("LinkedList search out of range."); } template const T& LinkedList::search(const std::function& cmp) const { for (auto i = head; i; i = i->next) { if (cmp(i->data))return i->data; } throw std::out_of_range("LinkedList search out of range."); } template LinkedList LinkedList::searchAll(const std::function& cmp) { LinkedList li; for (auto i = head; i; i = i->next) { if (cmp(i->data)) li.add(i->data); } return li; } template LinkedList LinkedList::searchAll(const std::function& cmp) const { LinkedList li; for (auto i = head; i; i = i->next) { if (cmp(i->data)) li.add(i->data); } return li; } #endif // !__LinkedList_CPP__