@@ -165,6 +165,140 @@ private:
165165
166166
167167## 其他语言版本
168+ ### C++双链表法:
169+
170+ ```CPP
171+ //采用循环虚拟结点的双链表实现
172+ class MyLinkedList {
173+ public:
174+ // 定义双向链表节点结构体
175+ struct DList {
176+ int elem; // 节点存储的元素
177+ DList *next; // 指向下一个节点的指针
178+ DList *prev; // 指向上一个节点的指针
179+ // 构造函数,创建一个值为elem的新节点
180+ DList(int elem) : elem(elem), next(nullptr), prev(nullptr) {};
181+ };
182+
183+ // 构造函数,初始化链表
184+ MyLinkedList() {
185+ sentinelNode = new DList(0); // 创建哨兵节点,不存储有效数据
186+ sentinelNode->next = sentinelNode; // 哨兵节点的下一个节点指向自身,形成循环
187+ sentinelNode->prev = sentinelNode; // 哨兵节点的上一个节点指向自身,形成循环
188+ size = 0; // 初始化链表大小为0
189+ }
190+
191+ // 获取链表中第index个节点的值
192+ int get(int index) {
193+ if (index > (size - 1) || index < 0) { // 检查索引是否超出范围
194+ return -1; // 如果超出范围,返回-1
195+ }
196+ int num;
197+ int mid = size >> 1; // 计算链表中部位置
198+ DList *curNode = sentinelNode; // 从哨兵节点开始
199+ if (index < mid) { // 如果索引小于中部位置,从前往后遍历
200+ for (int i = 0; i < index + 1; i++) {
201+ curNode = curNode->next; // 移动到目标节点
202+ }
203+ } else { // 如果索引大于等于中部位置,从后往前遍历
204+ for (int i = 0; i < size - index; i++) {
205+ curNode = curNode->prev; // 移动到目标节点
206+ }
207+ }
208+ num = curNode->elem; // 获取目标节点的值
209+ return num; // 返回节点的值
210+ }
211+
212+ // 在链表头部添加节点
213+ void addAtHead(int val) {
214+ DList *newNode = new DList(val); // 创建新节点
215+ DList *next = sentinelNode->next; // 获取当前头节点的下一个节点
216+ newNode->prev = sentinelNode; // 新节点的上一个节点指向哨兵节点
217+ newNode->next = next; // 新节点的下一个节点指向原来的头节点
218+ size++; // 链表大小加1
219+ sentinelNode->next = newNode; // 哨兵节点的下一个节点指向新节点
220+ next->prev = newNode; // 原来的头节点的上一个节点指向新节点
221+ }
222+
223+ // 在链表尾部添加节点
224+ void addAtTail(int val) {
225+ DList *newNode = new DList(val); // 创建新节点
226+ DList *prev = sentinelNode->prev; // 获取当前尾节点的上一个节点
227+ newNode->next = sentinelNode; // 新节点的下一个节点指向哨兵节点
228+ newNode->prev = prev; // 新节点的上一个节点指向原来的尾节点
229+ size++; // 链表大小加1
230+ sentinelNode->prev = newNode; // 哨兵节点的上一个节点指向新节点
231+ prev->next = newNode; // 原来的尾节点的下一个节点指向新节点
232+ }
233+
234+ // 在链表中的第index个节点之前添加值为val的节点
235+ void addAtIndex(int index, int val) {
236+ if (index > size) { // 检查索引是否超出范围
237+ return; // 如果超出范围,直接返回
238+ }
239+ if (index <= 0) { // 如果索引为0或负数,在头部添加节点
240+ addAtHead(val);
241+ return;
242+ }
243+ int num;
244+ int mid = size >> 1; // 计算链表中部位置
245+ DList *curNode = sentinelNode; // 从哨兵节点开始
246+ if (index < mid) { // 如果索引小于中部位置,从前往后遍历
247+ for (int i = 0; i < index; i++) {
248+ curNode = curNode->next; // 移动到目标位置的前一个节点
249+ }
250+ DList *temp = curNode->next; // 获取目标位置的节点
251+ DList *newNode = new DList(val); // 创建新节点
252+ curNode->next = newNode; // 在目标位置前添加新节点
253+ temp->prev = newNode; // 目标位置的节点的前一个节点指向新节点
254+ newNode->next = temp; // 新节点的下一个节点指向目标位置的结点
255+ newNode->prev = curNode; // 新节点的上一个节点指向当前节点
256+ } else { // 如果索引大于等于中部位置,从后往前遍历
257+ for (int i = 0; i < size - index; i++) {
258+ curNode = curNode->prev; // 移动到目标位置的后一个节点
259+ }
260+ DList *temp = curNode->prev; // 获取目标位置的节点
261+ DList *newNode = new DList(val); // 创建新节点
262+ curNode->prev = newNode; // 在目标位置后添加新节点
263+ temp->next = newNode; // 目标位置的节点的下一个节点指向新节点
264+ newNode->prev = temp; // 新节点的上一个节点指向目标位置的节点
265+ newNode->next = curNode; // 新节点的下一个节点指向当前节点
266+ }
267+ size++; // 链表大小加1
268+ }
269+
270+ // 删除链表中的第index个节点
271+ void deleteAtIndex(int index) {
272+ if (index > (size - 1) || index < 0) { // 检查索引是否超出范围
273+ return; // 如果超出范围,直接返回
274+ }
275+ int num;
276+ int mid = size >> 1; // 计算链表中部位置
277+ DList *curNode = sentinelNode; // 从哨兵节点开始
278+ if (index < mid) { // 如果索引小于中部位置,从前往后遍历
279+ for (int i = 0; i < index; i++) {
280+ curNode = curNode->next; // 移动到目标位置的前一个节点
281+ }
282+ DList *next = curNode->next->next; // 获取目标位置的下一个节点
283+ curNode->next = next; // 删除目标位置的节点
284+ next->prev = curNode; // 目标位置的下一个节点的前一个节点指向当前节点
285+ } else { // 如果索引大于等于中部位置,从后往前遍历
286+ for (int i = 0; i < size - index - 1; i++) {
287+ curNode = curNode->prev; // 移动到目标位置的后一个节点
288+ }
289+ DList *prev = curNode->prev->prev; // 获取目标位置的下一个节点
290+ curNode->prev = prev; // 删除目标位置的节点
291+ prev->next = curNode; // 目标位置的下一个节点的下一个节点指向当前节点
292+ }
293+ size--; // 链表大小减1
294+ }
295+
296+ private:
297+ int size; // 链表的大小
298+ DList *sentinelNode; // 哨兵节点的指针
299+ };
300+ ```
301+
168302### C:
169303
170304``` C
0 commit comments