链表(模板)类

链表类依赖于cmath头文件,使用ListNode,List四个文件实现:

ListNode.h:

 1 /*********************************************
 2 ListNode.h
 3 链表节点(模板)类 ListNode
 4 T 节点数据
 5 pred 前节点指针
 6 succ 后节点指针
 7 ListNode / ListNode(T, T*, T*) 构造
 8 InsertPred(T) 前插入节点
 9 InsertSucc(T) 后插入节点
10 
11  * Created by QSY 2020.10.11
12  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
13  * Department Of Automation, Tsinghua University
14  * Copyright (c) 2020. All rights reserved.
15 **********************************************/
16 #pragma once
17 
18 typedef int Rank; //
19 #define Posi(T) ListNode<T>* //列表节点指针
20 
21 template<typename T> 
22 struct ListNode
23 {
24     T data;//节点数据
25     Posi(T) pred;//前驱节点引用
26     Posi(T) succ;//后继节点引用
27     ListNode() {};//空构造
28     ListNode(T e, Posi(T) p = nullptr, Posi(T) s = nullptr)
29         :date(e), pred(p), succ(s) {};
30     Posi(T) InsertPred(T const& e);//前插入节点
31     Posi(T) InsertSucc(T const& e);//后插入节点
32 };

ListNode.cpp:

 1 /*********************************************
 2 ListNode.cpp
 3 
 4  * Created by QSY 2020.10.11
 5  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
 6  * Department Of Automation, Tsinghua University
 7  * Copyright (c) 2020. All rights reserved.
 8 **********************************************/
 9 
10 #include "ListNode.h"
11 
12 template<typename T>
13 Posi(T) ListNode<T>::InsertPred(T const& e) {
14     Posi(T) x = new ListNode(e, pred, this);
15     pred->succ = x;
16     this->pred = x;
17     return x;
18 }
19 
20 template<typename T>
21 Posi(T) ListNode<T>::InsertSucc(T const& e) {
22     Posi(T) x = new ListNode(e, this, succ);
23     succ->pred = x;
24     this->succ = x;
25     return x;
26 }
View Code

List.h:

 1 /*********************************************
 2 链表(模板)类 List
 3 本文件绝大多数函数未考虑非法输入情况,调用前请先依据源代码避免非法输入,否则程序的行为将不可预测
 4 
 5  * Created by QSY 2020.10.14
 6  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
 7  * Department Of Automation, Tsinghua University
 8  * Copyright (c) 2020. All rights reserved.
 9 **********************************************/
10 #pragma once
11 #include "ListNode.h"
12 
13 template<typename T>
14 class List
15 {
16 private:
17     Rank _size;//链表长度,不计头尾
18     Posi(T) header;
19     Posi(T) trailer;
20     //header first …… last trailer
21     //  -1     0        n   n + 1
22 //内部方法
23     //可以将p后的n个节点拷贝至当前对象
24     void CopyNodes(Posi(T) p, int n);
25     //重载swap函数作为内部方法
26     void swap(T, T);
27     void swap(Posi(T), Posi(T));
28 protected:
29     //初始化整个列表
30     void init();
31     //清除整个链表的数据,恢复为混沌初开的状态
32     void clear();
33     
34 public:
35 //构造函数
36     List() { init(); };
37     List(List<T> const& L);//整体复制列表L
38     List(List<T> const& L, Rank r, int n);//复制L中自第r项起的n项
39     List(Posi(T) p, int n);//复制列表中自位置p起的n项
40 //析构函数
41     ~List();
42 //
43     const Rank& const size = _size;
44     Rank size() const { return _size; }
45     bool empty() const { return _size <= 0; }
46 //节点操作接口
47     //r->data
48     T& operator[] (Rank r) const;//重载下标操作符,以通过秩直接访问列表节点数据
49     //r->p
50     Posi(T) posi(Rank r);//返回r节点的指针
51     Posi(T) posi(List<T> const& L, Rank r);//返回r节点的指针
52     //p->r
53     Rank rank(Posi(T) p);//返回当前指针的秩
54     //data->p
55     Posi(T) find(T const& e) const;
56     
57     Rank distance(Posi(T) p, Posi(T) q);//p在q前!
58     Posi(T) first() const;
59     Posi(T) last() const;
60     Posi(T) selectMax(Posi(T) p, int n);
61     
62 //写入删除接口
63     Posi(T) InsertFirst(T const& e);
64     Posi(T) InsertLast(T const& e);
65     Posi(T) InsertBefore(Posi(T) p, T const& e);
66     Posi(T) InsertAfter(Posi(T) p, T const& e);
67     T Remove(Posi(T) p);
68 //排序接口
69     void insert_sort();//invalid
70     void merge_sort();//o(nlogn)
71     Posi(T) merge_sort(Posi(T) p, int n);
72     Posi(T) merge(List<T> L, Posi(T) p, int n, Posi(T) q, int m);
73     void select_sort();//o(n^2)
74     void radix_sort();//invalid
75 //转置接口
76     void reverse();
77     void reverse(Posi(T) p1, Posi(T) p2);//p1在p2之前
78     void reverse(Rank r1, Rank r2);
79 };

List.cpp:

  1 /*********************************************
  2 List.cpp
  3 
  4  * Created by QSY 2020.10.11
  5  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
  6  * Department Of Automation, Tsinghua University
  7  * Copyright (c) 2020. All rights reserved.
  8 **********************************************/
  9 
 10 #include "List.h"
 11 #include <cmath>
 12 
 13 template<typename T>
 14 void List<T>::CopyNodes(Posi(T) p, int n) {
 15     if (!_size) {
 16         init();
 17     }
 18     else {
 19         clear();
 20     }
 21     while (n--) {
 22         InsertLast(p->data);
 23         p = p->succ;
 24     }
 25 }//有改进空间,栈空间占用过多
 26 
 27 template<typename T>
 28 void List<T>::swap(T t1, T t2) {
 29     T tt = t1;
 30     t1 = t2;
 31     t2 = tt;
 32 }
 33 
 34 template<typename T>
 35 void List<T>::swap(Posi(T) p1, Posi(T) p2) {
 36     Posi(T) pt = p1;
 37     p1 = p2;
 38     p2 = pt;
 39 }
 40 
 41 template<typename T>
 42 void List<T>::init() {
 43     header = new ListNode<T>;
 44     trailer = new ListNode<T>;
 45     header->succ = trailer;
 46     header->pred = nullptr;
 47     trailer->succ = nullptr;
 48     trailer->pred = header;
 49     _size = 0;
 50 }
 51 
 52 template<typename T>
 53 void List<T>::clear() {
 54     int oldsize = _size;
 55     while (0 < _size) {
 56         Remove(header->succ);
 57     }
 58 }
 59 
 60 template<typename T>
 61 List<T>::List(List<T> const& L) {
 62     CopyNodes(L.first(), L._size); 
 63 }
 64 
 65 template<typename T>
 66 List<T>::List(List<T> const& L, Rank r, int n) {
 67     Posi(T) p = Pos(L, r);
 68     CopyNodes(p, n);
 69 }
 70 
 71 template<typename T>
 72 List<T>::List(Posi(T) p, int n) {
 73     CopyNodes(p, n);
 74 }
 75 
 76 template<typename T>
 77 List<T>::~List() {
 78     clear();
 79     delete header;
 80     delete trailer;
 81 }
 82 
 83 template <typename T> 
 84 T& List<T>::operator[] (Rank r) const {
 85     return Pos(r)->data;
 86 }
 87 
 88 template<typename T>
 89 Posi(T) List<T>::posi(Rank r) {
 90     if (_size <= r) {
 91         return nullptr;
 92     }//特判,防止请求越界
 93     Posi(T) p = this->first();
 94     while (0 < r--) {
 95         p = p->succ;
 96     }
 97     return p;
 98 }
 99 
100 template<typename T>
101 Posi(T) List<T>::posi(List<T> const& L, Rank r) {
102     if (L.size <= r) {
103         return nullptr;
104     }//特判,防止请求越界
105     Posi(T) p = L.first();
106     while (0 < r--) {
107         p = p->succ;
108     }
109     return p;
110 }
111 
112 template<typename T>
113 Rank List<T>::rank(Posi(T) p) {
114     Rank r = 0;
115     Posi(T) ptr = trailer->succ;
116     while (p != ptr) {
117         ptr = ptr->succ;
118         ++r;
119     }
120     return 0;
121 }
122 
123 template<typename T>
124 Posi(T) List<T>::find(T const& e)const {
125     Posi(T) p = trailer->succ;
126     for (int i = 0; i < _size; ++i) {
127         if (p->data == T) {
128             return p;
129         }
130         p = p->succ;
131     }
132     return nullptr;
133 }
134 
135 template<typename T>
136 Rank List<T>::distance(Posi(T) p, Posi(T) q) {
137     Rank r = 0;
138     while (p != q) {
139         p = p->succ;
140         ++r;
141     }
142     return r;
143 }
144 
145 template<typename T>
146 Posi(T) List<T>::first() const {
147     if (_size) {
148         return header->succ;
149     }//特判,防止无长度
150     return nullptr;
151 }
152 
153 template<typename T>
154 Posi(T) List<T>::last() const {
155     if (_size) {
156         return trailer->pred;
157     }
158     return nullptr;
159 }
160 
161 template<typename T>
162 Posi(T) List<T>::selectMax(Posi(T) p, int n) {
163     Posi(T) max = p;
164     for (; 1 < n; n--) {
165         if (max->data <= p->data) {
166             max = p;
167         }
168         p = p->succ;
169     }
170     return max;
171 }
172 
173 template<typename T>
174 Posi(T) List<T>::InsertFirst(T const& e) {
175     _size++;
176     return header->InsertSucc(T);
177 }
178 
179 template<typename T>
180 Posi(T) List<T>::InsertLast(T const& e) {
181     _size++;
182     return trailer->InsertPred(T);
183 }
184 
185 template<typename T>
186 Posi(T) List<T>::InsertBefore(Posi(T) p, T const& e) {
187     _size++;
188     return p->InsertPred(T);
189 }
190 
191 template<typename T>
192 Posi(T) List<T>::InsertAfter(Posi(T) p, T const& e) {
193     _size++;
194     return p->InsertSucc(T);
195 }
196 
197 template<typename T>
198 T List<T>::Remove(Posi(T) p) {
199     T e = p->data;//备份数据
200     //更新指针指向,拆出链表
201     p->pred->succ = p->succ;
202     p->succ->pred = p->pred;
203     delete p;//释放空间
204     _size--;
205     return e;
206 }
207 
208 template<typename T>
209 void List<T>::insert_sort() {
210     //
211 }
212 
213 template<typename T>
214 void List<T>::merge_sort() {
215     merge_sort(first(), _size);
216 }
217 
218 template<typename T>
219 Posi(T) List<T>::merge_sort(Posi(T) p, int n) {
220     Posi(T) pp = p->pred;
221     Posi(T) q = p;
222     int m = n >> 2;
223     for (int i = 0; i < m; ++i) {
224         q = q->succ;
225     }
226     merge_sort(p, m);
227     merge_sort(q, n - m);
228     merge(this, p, m, q, n - m);
229     return pp->succ;
230 }
231 
232 template<typename T>
233 Posi(T) merge(List<T> L, Posi(T) p, int n, Posi(T) q, int m) {
234     Posi(T) pp = p->pred;
235     while (0 < m) {//在q未移出区间之前
236         if ((0 < n) && p->data <= q->data) {//p未移出区间且p的数据更小
237             p = p->succ;
238             --n;
239         }
240         else {
241             q = q->succ;
242             InsertBefore(p, L.Remove(q->pred));
243             --m;
244         }
245     }
246     return pp->succ;
247 }
248 
249 template<typename T>
250 void List<T>::select_sort() {
251     int n = _size;
252     Posi(T) first = first();
253     Posi(T) tail = trailer;
254     while (1 < n) {
255         Posi(T) max = selectMax(first, n);
256         InsertBefore(tail, Remove(max);
257         tail = tail->pred;
258         --n;
259     }
260 }
261 
262 template<typename T>
263 void List<T>::radix_sort() {
264     //
265 }
266 
267 template<typename T>
268 void List<T>::reverse() {
269     if (_size < 2) {
270         return;
271     }
272     Posi(T) p = header; 
273     Posi(T) q = trailer;
274     for (int i = 1; i < _size; i += 2) {
275         p = p->succ;
276         q = q->pred;
277         swap(p->data, q->data);
278     }
279 }
280 
281 template<typename T>
282 void List<T>::reverse(Posi(T) p1, Posi(T) p2) {
283     int n = distance(p1, p2) + 1;
284     for (int i = 1; i < n; i += 2) {
285         swap(p1->data, p2->data);
286         p1 = p1->succ;
287         p2 = p2->pred;
288     }
289 }
290 
291 template<typename T>
292 void List<T>::reverse(Rank r1, Rank r2) {
293     int n = abs(r2 - r1);
294     if (n < 2) {
295         return;
296     }
297     if (r1 < r2) {
298         Posi(T) p = posi(r1);
299         Posi(T) q = posi(r2);
300     }
301     else {
302         Posi(T) q = posi(r1);
303         Posi(T) p = posi(r2);
304     }
305     for (int i = 1; i < n; i += 2) {
306         swap(p->data, q->data);
307         p = p->succ;
308         q = q->pred;
309     }
310 }
View Code

//2020.10.15更新,暂未测试

 

posted @ 2020-10-15 00:06  MergusSquamatus  阅读(329)  评论(6编辑  收藏  举报