C++双向循环链表

先说一说双向循环链表的逆置,网上搜了一箩筐,用VS2017,基本上不成功,尽管明白道理是怎么回事,但是总感觉,不像c++的类,感觉用起来还得传指针啊,传链表啊等参数,不太像双向循环链表类的专属函数。虽然c语言写出来双向循环链表最好,但是既然学了c++,就尽量用一下c++的特点,能用多少是多少,也有利于对c++理解。好了废话不多说,凉一凉自己写的一般一般的双向循环链表吧。

  1 #include<iostream>
  2 
  3 using namespace std;
  4 
  5 template<class T> class DoubleLinkedList;
  6 
  7 template<class T>
  8 class MyNode    
  9 {
 10     friend class DoubleLinkedList<T>;
 11 private:
 12     T elem;
 13     MyNode *prev;
 14     MyNode *next;
 15     MyNode(){}
 16     MyNode(const T &theelem)
 17         :elem(theelem) {
 18         prev = NULL;
 19         next = NULL;
 20     }
 21 };
 22 
 23 template<class T>
 24 class DoubleLinkedList
 25 {
 26 public:
 27     DoubleLinkedList() 
 28     {
 29         first = new MyNode<T>(); 
 30         first->prev = first->next = first;
 31     }
 32     ~DoubleLinkedList(){ makeEmpty(); }
 33 
 34     bool IsEmpty(); // 判断链表是否为空
 35     void makeEmpty(); // 清空链表
 36     int  Length(); // 计算链表的长度
 37     void Insert(int index, const T &x); // 按照索引插入值(节点)
 38     void Push_head(const T &x); // 向链表的头部插入值  头插法
 39     void Push_back(const T &x); // 向链表的尾部插入值  尾插法
 40     void Delete(T x); // 按值删除节点
 41     void Index_Delete(const int &n); // 按索引删除节点
 42     void Invert(); // 逆置
 43     void Concatenate(DoubleLinkedList<T> &b); // 连接链表
 44     void show(); // 显示链表,这只是方便,一般得做成迭代器
 45 private:
 46     MyNode<T> *first;
 47 };
 48 template<class T>
 49 bool DoubleLinkedList<T>::IsEmpty()
 50 {
 51     return first == NULL;
 52 }
 53 
 54 template<class T>
 55 void DoubleLinkedList<T>::makeEmpty()
 56 {
 57     MyNode<T> *p;
 58     MyNode<T> *pNode = first->next;
 59     while (pNode != first)
 60     {
 61         p = pNode;
 62         pNode = pNode->next;
 63         delete p;
 64     }
 65     delete first;
 66     first = NULL;
 67 }
 68 
 69 template<class T>
 70 int  DoubleLinkedList<T>::Length()
 71 {
 72     int size = 0;
 73     MyNode<T> * p = first->next;
 74     if (IsEmpty()) cout << "The size is 0" << endl;
 75     else
 76     {
 77         while (p != first)
 78         {
 79             size++;
 80             p = p->next;
 81         }
 82     }
 83     return size;
 84 }
 85 
 86 template<class T>
 87 void DoubleLinkedList<T>::Insert(int index, const T &x)
 88 {
 89     MyNode<T> * insertNode = new MyNode<T>(x);
 90     MyNode<T> * p = first->next;
 91     if (Length() < index) {
 92         Push_back(x);
 93         return;
 94     }
 95     if (index < 1) {
 96         Push_head(x);
 97         return;
 98     }
 99     int count = 1;
100     while (count < index && p != first)
101     {
102         count++;
103         p = p->next;
104     }
105     insertNode->next = p;
106     p->prev->next = insertNode;
107     insertNode->prev = p->prev;
108     p->prev = insertNode;
109     return;
110 }
111 
112 template<class T>
113 void DoubleLinkedList<T>::Push_head(const T &x)
114 {
115     MyNode<T>* newNode = new MyNode<T>(x);
116     newNode->prev = first;
117     newNode->next = first->next;
118     first->next->prev = newNode;
119     first->next = newNode;
120 }
121 
122 template<class T>
123 void DoubleLinkedList<T>::Push_back(const T &x)
124 {
125     MyNode<T>* newNode = new MyNode<T>(x);
126     newNode->prev = first->prev;
127     newNode->next = first;
128     first->prev->next = newNode;
129     first->prev = newNode;
130 }
131 
132 template<class T>
133 void DoubleLinkedList<T>::Delete(T x)
134 {
135     MyNode<T>* p = first->next;
136     while (p->elem != x && p != first)
137     {
138         p = p->next;
139     }
140     p->next->prev = p->prev;
141     p->prev->next = p->next;
142     delete p;
143     return;
144 }
145 
146 template<class T>
147 void DoubleLinkedList<T>::Index_Delete(const int &n)
148 {
149     MyNode<T>* del = NULL;
150     MyNode<T>* p = first->next;
151     int count = 0;
152     if (n < 0)
153     {
154         del = p;
155         p->next->prev = first;
156         first->next = p->next;
157         delete del;
158         return;
159     }
160     else if(n > Length())
161     {
162         del = first->prev;
163         first->prev = del->prev;
164         del->prev->next = first;
165         delete del;
166         return;
167     }
168     while (count < n && p != first)
169     {
170         count++;
171         p = p->next;
172     }
173     del = p;
174     p->next->prev = p->prev;
175     p->prev->next = p->next;
176     delete del;
177 }
178 
179 template<class T>
180 void DoubleLinkedList<T>::Invert()
181 {
182         // 我这里只考虑链表至少有一个实数节点的情况
183         // 让p指向下一个节点,再把首节点与第一个实数节点做成一个循环链表,
184     MyNode<T>* p = first->next;
185     MyNode<T>* q = p;
186     p = p->next;
187     first->prev = q;
188     q->next = first;
189 
190        // 只要把接下来的节点一个一个放到头部就行了
191     while (p != first)
192     {
193         MyNode<T> *r;
194         r = p;
195         p = p->next;
196         r->prev = first;
197         r->next = first->next;
198         first->next->prev = r;
199         first->next = r;
200     }
201 }
202 
203 // 我选择将循环链表b的数值直接放到所连接链表的后面,这样改变b就不会改变连接后的链表
204 
205 template<class T>
206 void DoubleLinkedList<T>::Concatenate(DoubleLinkedList<T> &b)
207 {
208     MyNode<T>* p = b.first;
209     
210     if(IsEmpty())
211     {
212         first = p;
213     }
214     else if(b.IsEmpty())
215     {
216         return;
217     }
218     else {
219         while (p->next != b.first)
220         {
221             p = p->next;
222             Push_back(p->elem);
223         }
224         return;
225     }
226     return;
227 }
228 
229 template<class T>
230 void DoubleLinkedList<T>::show()
231 {
232     if (IsEmpty())
233     {
234         return;
235     }
236     MyNode<T>* p=first->next;
237     while (p != first)
238     {
239         cout << p->elem << " ";
240         p = p->next;
241     }
242     cout << endl;
243 
244 }
245 
246 // 下面测试的代码没啥可看的
247 
248 int main()
249 {
250     cout << "hello world!" << endl;
251 
252     DoubleLinkedList<int> a;
253     a.Push_head(30);
254     a.Push_head(20);
255     a.Push_head(10);
256     a.Push_back(40);
257     a.Push_back(50);
258     a.Push_back(60);
259     a.Index_Delete(2);
260     a.show();
261     a.Insert(1, 35);
262     a.Insert(-1, 100);
263     a.show();
264     int size;
265     
266     a.Delete(100);
267     size = a.Length();
268     a.Index_Delete(20);
269     a.show();
270     cout << "size: " << size << endl;
271 
272     DoubleLinkedList<int> intList;
273     DoubleLinkedList<int> intList1;
274 
275     intList.Push_back(1);
276     intList.Push_back(2);
277     intList.Push_back(3);
278     intList.Push_back(4);
279 
280     intList1.Push_back(5);
281     intList1.Push_back(6);
282     intList1.Push_back(7);
283     intList1.Push_back(8);
284     intList.Concatenate(intList1);
285     intList.show();
286     intList.Invert();
287     intList.show();
288     intList.Push_head(125);
289     intList.Push_back(21);
290     intList.Invert();
291     intList.show();
292     intList1.Delete(5);
293     intList1.Delete(6);
294     intList1.Delete(7);
295     intList1.Delete(8);
296     intList1.show();
297     return 0;
298 }      
原文地址:https://www.cnblogs.com/yang901112/p/12721425.html