1
+ #include < iostream>
2
+ using namespace std ;
3
+ struct Data {
4
+ int num;
5
+ Data *next;
6
+ };
7
+ void clear_list (Data *head) { // 递归回收*head之后的所有动态内存
8
+ if (head->next == nullptr ) // 如果*head之后没有动态内存
9
+ return ; // 那就不需要回收什么了,直接return;结束本次调用
10
+ clear_list (head->next ); // 先清理head->next之后的部分
11
+ delete head->next ; // 再回收head.next
12
+ head->next = nullptr ;
13
+ // 现在head之后没有动态内存了,我们可以放心地把head->next置为nullptr
14
+ }
15
+ void insert_after (Data *head, int n) { // 在*head下一位置插入n
16
+ Data* p = { new Data{n,nullptr } }; // 分配动态内存,并初始化其num成员
17
+ p->next = head->next ; // 插入数据的下一位指向当前的*head->next
18
+ head->next = p; // head->next指向*p,注意顺序不要颠倒!
19
+ }
20
+ bool delete_after (Data *head) {
21
+ // 删除*head下一位置的数据,并返回true;若*head是末尾元素,删除失败,返回false
22
+ if (head->next == nullptr ) // 说明*head就是末尾元素
23
+ return false ; // *head是末尾元素,无法再删除后面内容
24
+ // 这里应当用else块,不过也可以省掉
25
+ // 因为if块内会直接return,所以后面的代码肯定是在条件为false情况下运行的
26
+ Data *p = head->next ; // 临时指针p指向*head->next
27
+ head->next = p->next ; // head->next指向更后一个元素
28
+ delete p; // 回收p指向的内存
29
+ return true ;
30
+ }
31
+ bool delete_after (Data *head, Data* tail) {
32
+ // 删除*head之后(不包含)直到*tail为止(包含)的单元。若删除失败,返回false
33
+ if (head == tail) // 说明没有任何数据需要清理
34
+ return false ; // 删除失败
35
+ if (tail == nullptr ) { // 说明我们需要删除*head之后的所有内容
36
+ clear_list (head); // 当然是用clear_list啦
37
+ return true ; // 删除成功
38
+ }
39
+ Data tmp_head {*head}; // 用*head来直接为tmp_head初始化
40
+ head->next = tail->next ; // 绕过待删除段,直接指向*tail->next
41
+ tail->next = nullptr ; // tail指向nullptr,现在待删除片段就被剥离出来了
42
+ clear_list (&tmp_head); // 以tmp_head为头,清理这段链表
43
+ return true ; // 删除成功
44
+ }
45
+ void transfer (Data *head, Data *tail, Data *dest) {
46
+ // 片段转移,把*head之后(不包含)直到*tail为止(包含)的单元移到*dest之后
47
+ if (head == tail || dest == nullptr ) // 这两种情况下转移没有意义
48
+ return ;
49
+ if (tail == nullptr ) { // 这种情况不方便我们处理,我们把tail改成指向末尾单元
50
+ for (tail = head; tail->next != nullptr ; tail = tail->next ) {
51
+ ; // for循环的逻辑是,从head开始找,直到tail->next==nullptr为止
52
+ }
53
+ if (head == tail) // 仍需当心head==tail的可能
54
+ return ;
55
+ }
56
+ swap (tail->next , dest->next ); // swap函数需要utility或string_view库
57
+ swap (head->next , dest->next ); // 是一种技巧,读者不必强求掌握
58
+ }
59
+ int main () {
60
+ Data head; // 链表头
61
+ insert_after (&head, 10 );
62
+ insert_after (head.next , 20 );
63
+ delete_after (&head);
64
+ std::cout << head.next ->num ; // 将输出20
65
+ clear_list (&head);
66
+ return 0 ;
67
+ }
0 commit comments