2.3 单链表

 

 

 

 

 

 ①不带头结点的单链表的实现(类模板)

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <ctime>
  4 ///无头结点
  5 using namespace std;
  6 //typedef int T;
  7 
  8 template <class T>
  9 struct LinkNode //结点定义
 10 {
 11     T data;//数据域
 12     LinkNode<T>* next;//链域
 13     LinkNode(const T& item, LinkNode<T>* ptr=NULL)
 14     {
 15         data = item;
 16         next = ptr;
 17     }
 18     LinkNode(LinkNode<T>* ptr=NULL)
 19     {
 20         next = ptr;
 21     }
 22 };
 23 
 24 template <class T>
 25 class List
 26 {
 27 private:
 28     LinkNode<T>* first;
 29 public:
 30     List();//构造函数
 31     List(const T& x);
 32     List(const List<T>& L);//拷贝构造函数
 33     List<T>& operator=(const List<T>& L);//赋值运算符函数
 34     ~List();//析构函数
 35 
 36     void InputFront(const T& elem);//头插法
 37     void InputRear(const T& elem);//尾插法
 38 
 39     void MakeEmpty();//清空链表
 40     int Length() const;//返回链表中结点个数
 41 
 42     LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
 43     LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空
 44     LinkNode<T>* getHead()const;
 45 
 46     bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x
 47     void SetData(int i, const T& x);//设置链表第i个元素为x
 48 
 49     bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x
 50     bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x
 51 
 52     bool IsEmpty() const;//返回链表是否为空
 53     bool IsFull() const;//返回链表是否为满
 54 
 55     void CopyList(const List<T>& L);//复制链表
 56 
 57     void Sort();//对链表中结点进行排序
 58 
 59     friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载
 60     {
 61         LinkNode<T> *p=L.first;
 62        // p = p->next;
 63         while(p!=NULL)
 64         {
 65             cout << p->data << ' ';
 66             p = p->next;
 67         }
 68         cout << endl;
 69         return out;
 70     }
 71     //  friend istream& operator>>(istream& in, List& L);//输入流运算符重载
 72 };
 73 
 74 template <class T>
 75 List<T>::List()//构造函数
 76 {
 77     first = NULL;
 78 }
 79 
 80 template <class T>
 81 List<T>::List(const T& x)  //构造函数
 82 {
 83     first = new LinkNode<T>(x);
 84 }
 85 
 86 template <class T>
 87 List<T>::List(const List<T>& L)//拷贝构造函数
 88 {
 89     T temp;
 90     LinkNode<T>* strL = L.getHead();
 91     //cout <<L.getHead()<<endl;
 92     temp = strL->data;
 93     LinkNode<T>* strthis = first = new LinkNode<T>(temp);
 94     //cout <<first<<endl;
 95     while(strL->next)
 96     {
 97         temp = strL->next->data;
 98        // cout<<temp<<endl;
 99         strthis->next = new LinkNode<T>(temp);
100         strthis = strthis->next;
101         strL = strL->next;
102     }
103     strthis->next = NULL;
104 }
105 
106 template <class T>
107 LinkNode<T>* List<T>::getHead()const
108 {
109     return first;
110 }
111 
112 
113 template <class T>
114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数
115 {
116     T temp;
117     LinkNode<T>* strL = L.getHead();
118     //cout <<L.getHead()<<endl;
119     temp = strL->data;
120     LinkNode<T>* strthis = first = new LinkNode<T>(temp);  ///注意在这里要附上初值,要不然会多一个
121     //cout <<first<<endl;
122     while(strL->next)
123     {
124         temp = strL->next->data;
125        // cout<<temp<<endl;
126         strthis->next = new LinkNode<T>(temp);
127         strthis = strthis->next;
128         strL = strL->next;
129     }
130     strthis->next = NULL;
131     return *this;
132 }
133 
134 template <class T>
135 List<T>::~List()//析构函数
136 {
137     MakeEmpty();
138 }
139 
140 template <class T>
141 void List<T>::InputFront(const T& elem)//头插法
142 {
143     MakeEmpty();
144     LinkNode<T> *temp = new LinkNode<T>(elem);
145     if(temp == NULL)
146         exit(1);
147     temp->next = first;
148     first = temp;
149 }
150 
151 template <class T>
152 void List<T>::InputRear(const T& elem)//尾插法
153 {
154     LinkNode<T> *temp;
155     MakeEmpty();
156     temp = new LinkNode<T>(elem);
157     if(first == NULL) //要考虑没有元素的情况
158         first = temp;
159     else
160     {
161         LinkNode<T> *current = first;
162         while(current->next)
163         {
164             current = current->next;
165         }
166         current->next = temp;
167     }
168     return;
169 }
170 
171 template <class T>
172 void List<T>::MakeEmpty()//清空链表
173 {
174     LinkNode<T> *q;
175     while(first != NULL)
176     {
177         q = first;
178         first = q->next;
179         delete q;
180     }
181 }
182 
183 template <class T>
184 int List<T>::Length() const//返回链表中结点个数
185 {
186     int len = 0;
187     LinkNode<T> *p = first;
188     while(p)
189     {
190         p=p->next;
191         len++;
192     }
193     return len;
194 }
195 
196 template <class T>
197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
198 {
199     LinkNode<T> *p = first;
200     while(p)
201     {
202         if(p->data == x)
203             return p;
204         p = p->next;
205     }
206 }
207 
208 template <class T>
209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空
210 {
211     if(i<=0)
212         return NULL;
213     LinkNode<T> *p = first;
214     int m = 1;
215     while(p->next != NULL && m<i)
216     {
217         p = p->next;
218         m++;
219     }
220     return p;
221 }
222 
223 template <class T>
224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x
225 {
226     if(i <= 0)
227         return NULL;
228     LinkNode<T> *p = Locate(i);
229     if(p == NULL)
230         return false;
231     x = p->data;
232     return true;
233 }
234 
235 template <class T>
236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x
237 {
238     if(i <= 0)
239         return;
240     LinkNode<T> *p = Locate(i);
241     if(p == NULL)
242         return;
243     p->data = x;
244 }
245 
246 template <class T>
247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x
248 {
249     if((first == NULL) || (i == 0))
250     {
251         LinkNode<T> *newNode = new LinkNode<T>(x);
252         if(newNode == NULL)
253         {
254             cerr << "存储分配错误!";
255             exit(1);
256         }
257         newNode->next = first;
258         first = newNode;
259     }
260     else
261     {
262         LinkNode<T> *pre = first;
263         for(int j = 1; j < i; j++)
264         {
265             if(pre->next == NULL)
266                 break;
267             else
268                 pre = pre -> next;
269         }
270         if(pre == NULL)
271         {
272             cout << "无效的插入位置" << endl;
273             return false;
274         }
275         else
276         {
277             LinkNode<T> *newNode = new LinkNode<T>(x);
278             newNode -> next = pre -> next;
279             pre -> next = newNode;
280         }
281     }
282     return true;
283 }
284 
285 template <class T>
286 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x
287 {
288     LinkNode<T> *p = Locate(i-1);
289     if(p == NULL)
290         return false;
291     LinkNode<T> *del = p->next;
292     x = del->next->data;
293     p->next = del->next;
294 
295     delete del;
296     return true;
297 }
298 
299 template <class T>
300 bool List<T>::IsEmpty() const//返回链表是否为空
301 {
302     if(first = NULL)
303         return true;
304     else
305         return false;
306 }
307 
308 template <class T>
309 bool List<T>::IsFull() const//返回链表是否为满
310 {
311     return false;
312 }
313 
314 template <class T>
315 void List<T>::CopyList(const List& L)                     //复制链表
316 {
317     LinkNode<T> *iter = new LinkNode<T>;
318     LinkNode<T> *rear = new LinkNode<T>;
319     if(L.first == NULL)
320         return;
321     LinkNode<T> *newNode = new LinkNode<T>(L.first -> data);
322     first = newNode;
323     iter = L.first -> next;
324     rear = newNode;
325     while(iter)
326     {
327         LinkNode<T> *newNode = new LinkNode<T>(iter -> data);
328         rear -> next = newNode;
329         iter = iter -> next;
330         rear = rear -> next;
331     }
332 }
333 
334 
335 template <class T>
336 void List<T>::Sort()//对链表中结点进行排序
337 {
338     LinkNode<T> *current = this->first;
339     int temp;
340     while(current->next != NULL)
341     {
342         LinkNode<T>* second = current->next;
343         while(second != NULL)
344         {
345             if((current->data) > (second->data))
346             {
347                 temp = current->data;
348                 current->data = second->data;
349                 second->data = temp;
350             }
351             second = second->next;
352         }
353         current = current->next;
354     }
355 }
356 
357 
358 //template <class T>
359 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载
360 //{
361 
362 //}
363 
364 int main()
365 {
366     List<int> lst;
367     srand(time(NULL));
368     for(int i=1; i<=5; i++)
369         lst.Insert(i,rand()%50);
370     cout << "past: " <<lst;
371     cout <<endl;
372 
373     lst.SetData(3,999);
374     cout<<"SetData,No.3=99: "<<lst;
375     cout <<endl;
376 
377     lst.Sort();
378     cout << "sort: " << lst;
379     cout <<endl;
380 
381     int val;
382     lst.Remove(2,val);
383     cout << "remove:(second) " << lst;
384    // cout<<"FIRST:   "<<lst.getHead()<<endl;
385     cout <<endl;
386 
387     List<int> lst1 = lst;
388    // cout<<"FIRST:   "<<lst1.getHead()<<endl;
389     cout << lst1;
390     lst.MakeEmpty();
391     lst = lst1;
392   //  cout<<"FIRST:   "<<lst.getHead()<<endl;
393     cout << lst;
394 
395     return 0;
396 }

#调试结果#

 

 

 

 

②带头结点的单链表的实现(类模板)

 

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <ctime>
  4 ///带头结点
  5 using namespace std;
  6 //typedef int T;
  7 
  8 template <class T>
  9 struct LinkNode //结点定义
 10 {
 11     T data;//数据域
 12     LinkNode<T>* next;//链域
 13     LinkNode(const T& item, LinkNode<T>* ptr=NULL)
 14     {
 15         data = item;
 16         next = ptr;
 17     }
 18     LinkNode(LinkNode<T>* ptr=NULL)
 19     {
 20         next = ptr;
 21     }
 22 };
 23 
 24 template <class T>
 25 class List
 26 {
 27 private:
 28     LinkNode<T>* first;
 29 public:
 30     List();//构造函数
 31     List(const T& x);
 32     List(const List<T>& L);//拷贝构造函数
 33     List<T>& operator=(const List<T>& L);//赋值运算符函数
 34     ~List();//析构函数
 35 
 36     void InputFront(const T& elem);//头插法
 37     void InputRear(const T& elem);//尾插法
 38 
 39     void MakeEmpty();//清空链表
 40     int Length() const;//返回链表中结点个数
 41 
 42     LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
 43     LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空
 44     LinkNode<T>* getHead()const;
 45 
 46     bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x
 47     void SetData(int i, const T& x);//设置链表第i个元素为x
 48 
 49     bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x
 50     bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x
 51 
 52     bool IsEmpty() const;//返回链表是否为空
 53     bool IsFull() const;//返回链表是否为满
 54 
 55     void CopyList(const List<T>& L);//复制链表
 56 
 57     void Sort();//对链表中结点进行排序
 58 
 59     friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载
 60     {
 61         LinkNode<T> *p=L.first;
 62         p = p->next;
 63         while(p!=NULL)
 64         {
 65             cout << p->data << ' ';
 66             p = p->next;
 67         }
 68         cout << endl;
 69         return out;
 70     }
 71     //  friend istream& operator>>(istream& in, List& L);//输入流运算符重载
 72 };
 73 
 74 template <class T>
 75 List<T>::List()//构造函数
 76 {
 77     first = new LinkNode<T>;  //first不指向NULL了,指向一个头结点
 78 }
 79 
 80 template <class T>
 81 List<T>::List(const T& x)  //构造函数
 82 {
 83     first = new LinkNode<T>(x);
 84 }
 85 
 86 template <class T>
 87 List<T>::List(const List<T>& L)//拷贝构造函数
 88 {
 89     T temp;
 90     LinkNode<T>* strL = L.getHead();
 91     //cout <<L.getHead()<<endl;
 92     // temp = strL->data;
 93     LinkNode<T>* strthis = first = new LinkNode<T>;  //这里也进行了更改
 94     //cout <<first<<endl;
 95     while(strL->next)
 96     {
 97         temp = strL->next->data;  //change
 98         // cout<<temp<<endl;
 99         strthis->next = new LinkNode<T>(temp);
100         strthis = strthis->next;
101         strL = strL->next;
102     }
103     strthis->next = NULL;
104 }
105 
106 template <class T>
107 LinkNode<T>* List<T>::getHead()const
108 {
109     return first;
110 }
111 
112 
113 template <class T>
114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数
115 {
116     T temp;
117     LinkNode<T>* strL = L.getHead();
118     //cout <<L.getHead()<<endl;
119     //temp = strL->data;
120     LinkNode<T>* strthis = first = new LinkNode<T>;
121     //cout <<first<<endl;
122     while(strL->next)
123     {
124         temp = strL->next->data;
125         // cout<<temp<<endl;
126         strthis->next = new LinkNode<T>(temp);
127         strthis = strthis->next;
128         strL = strL->next;
129     }
130     strthis->next = NULL;
131     return *this;
132 }
133 
134 template <class T>
135 List<T>::~List()//析构函数
136 {
137     MakeEmpty();
138 }
139 
140 template <class T>
141 void List<T>::InputFront(const T& elem)//头插法
142 {
143     MakeEmpty();
144     LinkNode<T> *temp = new LinkNode<T>(elem);
145     if(temp == NULL)
146         exit(1);
147     temp->next = first;
148     first = temp;
149 }
150 
151 template <class T>
152 void List<T>::InputRear(const T& elem)//尾插法
153 {
154     LinkNode<T> *temp;
155     MakeEmpty();
156     temp = new LinkNode<T>(elem);
157     if(first == NULL) //要考虑没有元素的情况
158         first = temp;
159     else
160     {
161         LinkNode<T> *current = first;
162         while(current->next)
163         {
164             current = current->next;
165         }
166         current->next = temp;
167     }
168     return;
169 }
170 
171 template <class T>
172 void List<T>::MakeEmpty()//清空链表
173 {
174     LinkNode<T> *q;
175     while(first->next != NULL) ///这里所有的first都要修改->next
176     {
177         q = first->next;
178         first->next = q->next;
179         delete q;
180     }
181 }
182 
183 template <class T>
184 int List<T>::Length() const//返回链表中结点个数
185 {
186     int len = 0;
187     LinkNode<T> *p = first->next;  ///++++++
188     while(p)
189     {
190         p=p->next;
191         len++;
192     }
193     return len;
194 }
195 
196 template <class T>
197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
198 {
199     LinkNode<T> *p = first->next;   ///++++++
200     while(p)
201     {
202         if(p->data == x)
203             return p;
204         p = p->next;
205     }
206 }
207 
208 template <class T>
209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空
210 {
211     if(i<0)
212         return NULL;
213     LinkNode<T> *p = first;
214     int m = 1;
215     while(p != NULL && m<i)  ///直接操作就行
216     {
217         p = p->next;
218         m++;
219     }
220     return p;
221 }
222 
223 template <class T>
224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x
225 {
226     if(i <= 0)
227         return NULL;
228     LinkNode<T> *p = Locate(i);
229     if(p == NULL)
230         return false;
231     x = p->data;
232     return true;
233 }
234 
235 template <class T>
236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x
237 {
238     if(i <= 0)
239         return;
240     LinkNode<T> *p = Locate(i+1);
241     if(p == NULL)
242         return;
243     p->data = x;
244 }
245 
246 template <class T>
247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x
248 {
249 
250     LinkNode<T> *pre = Locate(i);  ///有的时候不要自己写那么麻烦,直接使用函数,再比如copyList
251 
252     if(pre == NULL)
253         return false;
254 
255     LinkNode<T> *newNode = new LinkNode<T>(x);
256     newNode -> next = pre -> next;
257     pre -> next = newNode;
258 
259     return true;
260 }
261 
262 template <class T>
263 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x
264 {
265     LinkNode<T> *p = Locate(i);
266     if(p == NULL || p->next == NULL)
267         return false;
268     LinkNode<T> *del = p->next;
269     x = del->data;
270     p->next = del->next;
271 
272     delete del;
273     return true;
274 }
275 
276 template <class T>
277 bool List<T>::IsEmpty() const//返回链表是否为空
278 {
279     if(first->next = NULL)
280         return true;
281     else
282         return false;
283 }
284 
285 template <class T>
286 bool List<T>::IsFull() const//返回链表是否为满
287 {
288     return false;
289 }
290 
291 template <class T>
292 void List<T>::CopyList(const List& L)                     //复制链表
293 {
294     LinkNode<T> *iter = new LinkNode<T>;
295     LinkNode<T> *rear = new LinkNode<T>;
296     if(L.first == NULL)
297         return;
298     LinkNode<T> *newNode = new LinkNode<T>(L.first -> data);
299     first = newNode;
300     iter = L.first -> next;
301     rear = newNode;
302     while(iter)
303     {
304         LinkNode<T> *newNode = new LinkNode<T>(iter -> data);
305         rear -> next = newNode;
306         iter = iter -> next;
307         rear = rear -> next;
308     }
309 }
310 
311 
312 template <class T>
313 void List<T>::Sort()//对链表中结点进行排序
314 {
315     LinkNode<T> *current = this->first->next;
316     int temp;
317     while(current->next != NULL)
318     {
319         LinkNode<T>* second = current->next;
320         while(second != NULL)
321         {
322             if((current->data) > (second->data))
323             {
324                 temp = current->data;
325                 current->data = second->data;
326                 second->data = temp;
327             }
328             second = second->next;
329         }
330         current = current->next;
331     }
332 }
333 
334 
335 //template <class T>
336 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载
337 //{
338 
339 //}
340 
341 int main()
342 {
343     List<int> lst;
344     srand(time(NULL));
345     for(int i=1; i<=5; i++)
346         lst.Insert(i,rand()%50);
347     cout << "past: " <<lst;
348     cout <<endl;
349 
350     lst.SetData(3,999);
351     cout<<"SetData,No.3=999: "<<lst;
352     cout <<endl;
353 
354     lst.Sort();
355     cout << "sort: " << lst;
356     cout <<endl;
357 
358     int val;
359     lst.Remove(2,val);
360     cout << "remove:(second) " << lst;
361     // cout<<"FIRST:   "<<lst.getHead()<<endl;
362     cout <<endl;
363 
364     List<int> lst1 = lst;
365     // cout<<"FIRST:   "<<lst1.getHead()<<endl;
366     cout << lst1;
367     lst.MakeEmpty();
368     lst = lst1;
369     //  cout<<"FIRST:   "<<lst.getHead()<<endl;
370     cout << lst;
371 
372     return 0;
373 }

#调试结果#

 

posted @ 2020-09-29 08:42  ananasaa  阅读(137)  评论(0编辑  收藏  举报