Dandelion 1.1.1
A light-weight 3D builder for educational usage
载入中...
搜索中...
未找到
linked_list.hpp
浏览该文件的文档.
1#ifndef DANDELION_UTILS_LINKED_LIST_HPP
2#define DANDELION_UTILS_LINKED_LIST_HPP
3
4#include <cstddef>
5#include <utility>
6#include <type_traits>
7
8/*!
9 * \file utils/linked_list.hpp
10 * \ingroup utils
11 */
12
13// ------------------- Declarations ----------------------
14
15/*!
16 * \~chinese
17 * \brief 链表节点类型的基类。
18 *
19 * 若需要构造 `Node` 类型的链表,则 `Node` 类型应该继承这个类,
20 * 形成 CRTP (Curiously Recurring Template Pattern) 结构,从而为 `Node`
21 * 类添加侵入式链表所需的指针成员。
22 *
23 * \tparam Node 链表数据类型
24 */
25template<typename Node>
26struct LinkedListNode
27{
28 LinkedListNode();
29 Node* next_node;
30 Node* prev_node;
31};
32
33/*!
34 * \~chinese
35 * \brief 侵入式双链表。
36 *
37 * 这个类实现了一个通用侵入式双链表,允许尾插入(插入到 tail 之后)
38 * 和随机删除。
39 *
40 * \tparam Node 链表数据类型
41 */
42template<typename Node>
43class LinkedList
44{
45 static_assert(std::is_base_of_v<LinkedListNode<Node>, Node>,
46 "Type Node must inherit from LinkedListNode<Node>");
47
48public:
49 LinkedList();
50 ~LinkedList();
51 /*! \~chinese 链表头指针(非头节点,数据有意义)。 */
52 Node* head;
53 /*! \~chinese 链表尾指针。 */
54 Node* tail;
55 /*! \~chinese 在链表末尾插入一个元素,使用 `std::forward` 转发参数原地构造,无需移动。 */
56 template<typename... Args>
57 Node* append(Args&&... args);
58 /*! \~chinese 删除指针指向的节点。 */
59 void erase(Node* node);
60 /*! \~chinese 将指针指向的节点从链表中释放(删除),但不释放该节点的内存。 */
61 Node* release(Node* node);
62 /*! \~chinese 链表中存储的元素数量。 */
63 std::size_t size;
64};
65
66// ------------------- Definitions ----------------------
67
68template<typename Node>
69LinkedListNode<Node>::LinkedListNode() : next_node(nullptr), prev_node(nullptr)
70{
71}
72
73template<typename Node>
74LinkedList<Node>::LinkedList() : head(nullptr), tail(nullptr), size(0)
75{
76}
77
78template<typename Node>
79LinkedList<Node>::~LinkedList()
80{
81 Node* node = this->head;
82 while (node != nullptr) {
83 Node* to_be_deleted = node;
84 node = node->next_node;
85 delete to_be_deleted;
86 }
87}
88
89template<typename Node>
90template<typename... Args>
91Node* LinkedList<Node>::append(Args&&... args)
92{
93 Node* new_node = new Node(std::forward<Args>(args)...);
94 ++this->size;
95 if (this->head == nullptr) {
96 this->head = new_node;
97 this->tail = new_node;
98 return new_node;
99 }
100 this->tail->next_node = new_node;
101 new_node->prev_node = this->tail;
102 this->tail = new_node;
103 return new_node;
104}
105
106template<typename Node>
108{
109 if (node == nullptr || !this->size) {
110 return;
111 }
112 --this->size;
113 // Erase the last element in the list
114 if (!this->size) {
115 delete this->head;
116 this->head = nullptr;
117 this->tail = nullptr;
118 return;
119 }
120 Node* to_be_deleted = node;
121 // Erasure for the head node
122 if (node == this->head) {
123 this->head = this->head->next_node;
124 this->head->prev_node = nullptr;
125 delete to_be_deleted;
126 return;
127 }
128 // Erasure for the tail node
129 if (node == this->tail) {
130 this->tail = this->tail->prev_node;
131 this->tail->next_node = nullptr;
132 delete to_be_deleted;
133 return;
134 }
135 // Otherwise a general erasure
136 node->prev_node->next_node = node->next_node;
137 node->next_node->prev_node = node->prev_node;
138 delete to_be_deleted;
139}
140
141template<typename Node>
143{
144 if (node == nullptr || !this->size) {
145 return nullptr;
146 }
147 --this->size;
148 if (!this->size) {
149 // Erase the last element in the list
150 this->head = nullptr;
151 this->tail = nullptr;
152 } else if (node == this->head) {
153 // Erasure for the head node
154 this->head = this->head->next_node;
155 this->head->prev_node = nullptr;
156 } else if (node == this->tail) {
157 // Erasure for the tail node
158 this->tail = this->tail->prev_node;
159 this->tail->next_node = nullptr;
160 } else {
161 // Otherwise a general erasure
162 node->prev_node->next_node = node->next_node;
163 node->next_node->prev_node = node->prev_node;
164 }
165 return node;
166}
167
168#endif // DANDELION_UTILS_LINKED_LIST_HPP
Node * head
定义 linked_list.hpp:52
std::size_t size
定义 linked_list.hpp:63
void erase(Node *node)
定义 linked_list.hpp:107
Node * tail
定义 linked_list.hpp:54
Node * append(Args &&... args)
定义 linked_list.hpp:91
Node * release(Node *node)
定义 linked_list.hpp:142