C++数据结构 之 链表_Linked List
来源:互联网 发布:移民新西兰 知乎 编辑:程序博客网 时间:2024/06/14 06:48
C++数据结构 之 链表_Linked List
源代码只包含头文件
注:需要C++11的支持
一、链表
链表的思想类似于一根链子,环环相扣,每一个链环都是一个节点,每个节点中有自己的数据,还有指向前一个节点和后一个节点的指针。因此访问链表,不能随机访问,必须一个接一个,显然访问时间较长,但也是线性时间以内。
链表有头有尾,在本实现中,即使是空链表,头尾节点也是存在的。
支持的操作:
1、push_back (尾压入):将节点从尾部压入链表中。
2、push_front (首压入):将节点从首部压入链表中。
3、back 返回尾节点前一个节点的数据。
4、front 返回首节点下一个节点的数据。
5、front_insert 在当前节点的前一个位置一个新的节点。
6、back_front 在当先节点的下一个位置插入一个新的节点。
7、erase 删除当前节点,或者删除制定范围内的节点(此范围 [begin,end),注意括号的区别)。
8、clear 删除所有,初头尾节点以外的节点。
9、resize 添加n个默认初始化数据的节点
10、sort 按照数据less函数对象给链表排序。
11、search 返回所要查找数据的迭代器。
12、begin 返回首节点的下一个节点的迭代器。
13、end 返回尾节点的迭代器。
14 、rbegin 返回为节点的上一个节点的迭代器。
15、rend 返回首节点的迭代器。
示意图:
二、源代码:
#ifndef LIST_H#define LIST_H#include <memory>#include <stdexcept>#include <vector>#include <algorithm>using std::shared_ptr;using std::make_shared;template<typename Data>class List { friend class const_iterator;private: struct Node { Node() = default; Data data; shared_ptr<Node> prev = nullptr; shared_ptr<Node> next = nullptr; }; shared_ptr<Node> head = make_shared<Node>(); shared_ptr<Node> tail = make_shared<Node>(); void initialize() { head->next = tail; tail->prev = head; } size_t List_Size = 0;public: // CLASS const_iterator class const_iterator { friend class List<Data>; public: const_iterator() = default; ~const_iterator() = default; const_iterator(shared_ptr<Node> p) : ptr(p) {} const Data& operator*() const { return ptr->data; } const_iterator& operator+(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->next != nullptr) { ptr = ptr->next; } } return *this; } const_iterator& operator-(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->prev != nullptr) { ptr = ptr->prev; } } return *this; } const_iterator& operator++() { ptr = ptr->next; return *this; } const_iterator& operator++(int) { const_iterator temp = *this; ++*this; return temp; } const_iterator& operator--() { ptr = ptr->prev; return *this; } const_iterator& operator--(int) { const_iterator temp = *this; --*this; return temp; } bool operator==(const const_iterator &rhs) const { return ptr == rhs.ptr; } bool operator!=(const const_iterator &rhs) const { return !(*this == rhs); } protected: shared_ptr<Node> ptr; }; // CLASS iterator class iterator : public const_iterator { friend class List<Data>; public: iterator() = default; ~iterator() = default; Data& operator*() { return ptr->data; } const Data& operator*() const { return const_iterator::operator*(); } iterator& operator+(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->next != nullptr) { ptr = ptr->next; } } return *this; } iterator& operator-(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->prev != nullptr) { ptr = ptr->prev; } } return *this; } iterator& operator++() { ptr = ptr->next; return *this; } iterator& operator++(int) { iterator temp = *this; ++*this; return temp; } iterator& operator--() { ptr = ptr->prev; return *this; } iterator& operator--(int) { iterator temp = *this; --*this; return temp; } protected: iterator(shared_ptr<Node> p) : const_iterator(p) {} }; // CLASS const_reverse_iterator class const_reverse_iterator { friend class List<Data>; public: const_reverse_iterator() = default; ~const_reverse_iterator() = default; const_reverse_iterator(shared_ptr<Node> p) : ptr(p) {} const Data& operator*() const { return ptr->data; } const_reverse_iterator& operator+(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->prev != nullptr) { ptr = ptr->prev; } } return *this; } const_reverse_iterator& operator-(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->next != nullptr) { ptr = ptr->next; } } return *this; } const_reverse_iterator& operator++() { ptr = ptr->prev; return *this; } const_reverse_iterator& operator++(int) { const_reverse_iterator temp = *this; ++*this; return temp; } const_reverse_iterator& operator--() { ptr = ptr->next; return *this; } const_reverse_iterator& operator--(int) { const_reverse_iterator temp = *this; --*this; return temp; } bool operator==(const const_reverse_iterator& rhs) { return ptr == rhs.ptr; } bool operator!=(const const_reverse_iterator& rhs) { return !(*this == rhs); } protected: shared_ptr<Node> ptr; }; // CLASS reverse_iterator class reverse_iterator : public const_reverse_iterator { friend class List<Data>; public: reverse_iterator() = default; ~reverse_iterator() = default; Data& operator*() { return ptr->data; } const Data& operator*() const { return const_reverse_iterator::operator*(); } reverse_iterator& operator+(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->prev != nullptr) { ptr = ptr->prev; } } return *this; } reverse_iterator& operator-(long long LL) { for (auto i = 0; i != LL; ++i) { if (ptr->next != nullptr) { ptr = ptr->next; } } return *this; } reverse_iterator& operator++() { ptr = ptr->prev; return *this; } reverse_iterator& operator++(int) { reverse_iterator temp = *this; ++*this; return temp; } reverse_iterator& operator--() { ptr = ptr->next; return *this; } reverse_iterator& operator--(int) { reverse_iterator temp = *this; --*this; return temp; } protected: reverse_iterator(shared_ptr<Node> p) : const_reverse_iterator(p) {} };public: List() { initialize(); } ~List() = default; //List(const List &rhs) { // clear(); // for (auto &i : rhs) { // push_back(i); // } //} //List& operator=(const List &rhs) { // if (this == &rhs) { // return *this; // } // clear(); // for (auto &i : rhs) { // push_back(i); // } // return *this; //} iterator begin() { return iterator(head->next); } const_iterator begin() const { return const_iterator(head->next); } reverse_iterator rbegin() { return reverse_iterator(tail->prev); } const_reverse_iterator rbegin() const { return const_reverse_iterator(tail->prev); } iterator end() { return iterator(tail); } const_iterator end() const { return const_iterator(tail); } reverse_iterator rend() { return reverse_iterator(head); } const_reverse_iterator rend() const { return const_reverse_iterator(head); } // Front insert. iterator front_insert(iterator itr, const Data& data) { shared_ptr<Node> p = itr.ptr; ++List_Size; auto a = make_shared<Node>(); a->data = data; a->prev = p->prev; a->next = p; p->prev = a; a->prev->next = a; return iterator(a); //return iterator(p->prev = p->prev->next = make_shared<Node>(data, p->prev, p)); } iterator front_insert(iterator itr) { shared_ptr<Node> p = itr.ptr; ++List_Size; auto a = make_shared<Node>(); a->prev = p->prev; a->next = p; p->prev = a; a->prev->next = a; return iterator(a); } // Back_insert. iterator back_insert(iterator itr, const Data& data) { shared_ptr<Node> p = itr.ptr; ++List_Size; auto a = make_shared<Node>(); a->data = data; a->prev = p; a->next = p->next; p->next = a; a->next->prev = a; return iterator(a); //return iterator(p->next = p->next->prev = make_shared<Node>(data, p, p->next)); } iterator back_insert(iterator itr) { shared_ptr<Node> p = itr.ptr; ++List_Size; auto a = make_shared<Node>(); a->prev = p; a->next = p->next; p->next = a; a->next->prev = a; return iterator(a); } iterator erase(iterator itr) { shared_ptr<Node> p = itr.ptr; iterator itaval(p->next); try { if (p == head) { throw runtime_error("No elements can erase!"); } else if (p == tail) { throw runtime_error("No elements can erase!"); } else { p->prev->next = p->next; p->next->prev = p->prev; --List_Size; } } catch (runtime_error err) { cout << err.what() << endl; } return itaval; } iterator erase(iterator begin, iterator end) { // [begin, end) while (begin != end) { begin = erase(begin); } return iterator(end); } void clear() { while (!empty()) { pop_front(); } } void print() { for (auto &i : *this) { cout << i << endl; } } void resize(long long LL) { for (auto i = 0; i != LL; ++i) { push_back(); } } void resize(long long LL, const Data &x) { for (auto i = 0; i != LL; ++i) { push_back(x); } } void sort() { std::vector<Data> temp_v; for (auto &i : *this) { temp_v.push_back(i); } std::stable_sort(temp_v.begin(), temp_v.end()); clear(); for (auto &i : temp_v) { push_back(i); } } iterator search(const Data &x) { auto temp_count = 0; for (auto &i : *this) { if (i != x) { ++temp_count; } else { break; } } return begin() + temp_count; } bool empty() { return List_Size == 0; } size_t size() { return List_Size; } Data& front() { return *begin(); } const Data& front() const { return front(); } Data& back() { return *--end(); } const Data& back() const { return back(); } void push_front() { front_insert(begin()); } void push_front(const Data &x) { front_insert(begin(), x); } void push_back() { back_insert(--end()); } void push_back(const Data &x) { back_insert(--end(), x); } void pop_front() { erase(begin()); } void pop_back() { erase(--end()); }};#endif // !LIST_H
注释:所有对节点的访问,已经抽象成为使用迭代器访问。
- C++数据结构 之 链表_Linked List
- leetcode第一刷_Linked List Cycle
- leetcode第一刷_Linked List Cycle II
- 数据结构之 链表-Double-Ended List(2)
- java数据结构之List
- 数据结构List之ArrayList
- 数据结构List之Vector
- 数据结构List之LinkedList
- 【二】数据结构之List
- 数据结构之List
- 数据结构之vector&list
- Libevent分解之数据结构List
- 数据结构之list(用链表实现)
- Python基础数据结构之list
- Redis的数据结构之List
- scala数据结构之List列表
- 数据结构—链表List
- 数据结构:链表(linked-list)
- scrollUp.js Javascript/jQuery 页面返回顶部
- BLE 蓝牙 与APP 得交互 内设 外设
- NMEA-0183
- Android-自定义view之无所不能的path
- Java socket编程
- C++数据结构 之 链表_Linked List
- unity3d mask
- 用iSlider实现手机端图片轮转
- 【建议28:理解延迟求值和主动求值之间的区别】
- 字符串 KMP HDU 2203
- tomcat集群配置
- jquery 教程
- Window之消息循环机制
- Codeforces404C【构造】