单链表

用一组地址任意的存储单元存放线性表中的数据元素。   

以元素+ 指针= 结点

以“结点的序列”表示线性表称作线性链表(单链表)  

 单链表是一种顺序存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。   

因此,查找第 i 个数据元素的基本操作为:

移动指针,比较 j 和 i   单链表   1、链接存储方法   链接方式存储的线性表简称为链表(Linked List)。

链表的具体存储表示为:① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)   ② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))   

注意:链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。   

2、链表的结点结构   ┌──┬──┐   

                                │data│next│   

                                 └──┴──┘   

data域--存放结点值的数据域   next域--存放结点的直接后继的地址(位置)的指针域(链域)   注意:   

①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。   

②每个结点只有一个链域的链表称为单链表(Single Linked List)。

代码
1
2 #ifndef __SINGLE_LIST_H__
3  #define __SINGLE_LIST_H__
4 #endif
5
6 #include <assert.h>
7 /*#include <crtdbg.h>
8
9 #ifdef _DEBUG
10 #define DEBUG_NEW new (_NORMAL_BLOCK, THIS_FILE, __LINE__)
11 #endif
12
13 #ifdef _DEBUG
14 #define new DEBUG_NEW
15 #undef THIS_FILE
16 static char THIS_FILE[] = __FILE__;
17 #endif
18 */
19 #ifdef _DEBUG
20 #ifndef ASSERT
21 #define ASSERT assert
22 #endif
23 #else // not _DEBUG
24 #ifndef ASSERT
25 #define ASSERT
26 #endif
27 #endif // _DEBUG
28 #define NULL 0
29
30 template<typename T>
31 class Node
32 {
33 public:
34 Node(void):data(T()),next(NULL){}
35 Node(const Node &initdata):data(initdata),next(NULL){}
36 Node(const Node &initdata, Node<T> *cnext):data(initdata),next(cnext){}
37 public:
38 T data;
39 Node<T> *next;
40 };
41
42 template<typename T>
43 class Mylist
44 {
45 public:
46 Mylist();
47 Mylist(const T &initdata);
48 ~Mylist();
49
50 public:
51 int IsEmpty() const; //判断list是否为空
52 int GetCount() const; //获取list元素个数
53 int InsertBefore(const int pos, const T data); //pos前插
54 int InsertAfter(const int pos, const T data); //pos后插
55 int AddHead(const T data); //头插
56 int AddTail(const T data); //尾插法
57 void RemoveAt(const int pos); //删除某元素
58 void RemoveHead(); //删除头结点
59 void RemoveTail(); //删除尾结点
60 void RemoveAll(); //删除所有元素
61 T& GetTail(); //获取尾元素引用
62 T GetTail() const; //获取尾元素
63 T& GetHead(); //获取头结点引用
64 T GetHead() const; //获取头结点
65 T& GetAt(const int pos); //根据位置获取某元素引用
66 T GetAt(const int pos) const; //根据位置获取某元素
67 void SetAt(const int pos, T data); //修改特定位置的值
68 int Find(const T data) const; //查找元素
69
70 protected:
71 Node<T> *m_pNodeHead;
72 int m_nCount;
73
74 };
75
76 template<typename T>
77 inline Mylist<T>::Mylist():m_nCount(0),m_pNodeHead(NULL)
78 {
79 }
80
81 template<typename T>
82 inline Mylist<T>::Mylist(const T &initdata):m_nCount(0),m_pNodeHead(NULL)
83 {
84 AddHead(initdata);
85 }
86
87 template<typename T>
88 inline Mylist<T>::~Mylist()
89 {
90 RemoveAll();
91 }
92
93 template<typename T>
94 inline int Mylist<T>::IsEmpty() const
95 {
96 return NULL == m_pNodeHead;
97 }
98
99 template<typename T>
100 inline int Mylist<T>::GetCount() const
101 {
102 return m_nCount;
103 }
104
105 template<typename T>
106 int Mylist<T>::InsertBefore(const int pos, const T data)
107 {
108 Node<T> *pNewNode;
109 Node<T> *pNewNode1;
110 Node<T> *pNewNode2;
111 int npos;
112
113 pNewNode = new Node<T>;
114 if(NULL == pNewNode)
115 {
116 npos = 0;
117 goto Exit0;
118 }
119
120 pNewNode->data = data;
121 //pNewNode->next = NULL;//is default constructor is NULL
122
123 if (NULL == m_pNodeHead)
124 {
125 pNewNode->next = m_pNodeHead;
126 m_pNodeHead = pNewNode;
127 npos = 1;
128 goto Exit1;
129 }
130
131 ASSERT(1 <= pos && pos <= m_nCount);
132
133 pNewNode1 = m_pNodeHead;
134 for (int i = 1; i < pos; i++)
135 {
136 pNewNode2 = pNewNode1;
137 pNewNode1 = pNewNode1->next;
138 }
139
140 pNewNode->next = pNewNode1;
141 pNewNode2->next = pNewNode;
142
143 npos = pos;
144
145 Exit1:
146 ++m_nCount;
147 Exit0:
148 return npos;
149 }
150
151 // int InsertAfter(const int pos, const T data); //后插法
152 template<typename T>
153 int Mylist<T>::InsertAfter(const int pos, const T data)
154 {
155 Node<T> *pNewNode;
156 Node<T> *pNewNode1;
157 int npos;
158
159 pNewNode = new Node<T>;
160 if (NULL == pNewNode)
161 {
162 npos = 0;
163 goto Exit0;
164 }
165
166 pNewNode->data = data;
167
168 if(NULL == m_pNodeHead)
169 {
170 pNewNode->next = m_pNodeHead;
171 m_pNodeHead = pNewNode;
172 npos = 1;
173 goto Exit1;
174 }
175
176 ASSERT(1 <= pos && pos <= m_nCount);
177
178 pNewNode1 = m_pNodeHead;
179 for (int i = 1; i < pos; i++)
180 {
181 pNewNode1 = pNewNode1->next;
182 }
183
184 pNewNode->next = pNewNode1->next;
185 pNewNode1->next = pNewNode;
186 npos = pos+1;
187
188 Exit1:
189 ++m_nCount;
190 Exit0:
191 return npos;
192 }
193
194 //int AddHead(const T data); //头插
195 template<typename T>
196 int Mylist<T>::AddHead(const T data)
197 {
198 Node<T> *pNewNode;
199
200 pNewNode = new Node<T>;
201
202 if (NULL == pNewNode)
203 {
204 return 0;
205 }
206 pNewNode->data = data;
207 pNewNode->next = NULL;
208
209 if (NULL == m_pNodeHead)
210 {
211 pNewNode->next = m_pNodeHead;
212 m_pNodeHead = pNewNode;
213 m_nCount++;
214 return 1;
215 }
216
217 pNewNode->next = m_pNodeHead;
218 m_pNodeHead = pNewNode;
219 m_nCount++;
220 return 1;
221 }
222
223 // int AddTail(const T data); //尾插法
224
225 template<typename T>
226 inline int Mylist<T>::AddTail(const T data)
227 {
228 return InsertAfter(GetCount(), data);
229 }
230
231 //void RemoveAt(const int pos); //删除某元素
232 template<typename T>
233 void Mylist<T>::RemoveAt(const int pos)
234 {
235 ASSERT(1 <= pos && pos <= m_nCount);
236 Node<T> *pNewNode;
237 Node<T> *pTempNode;
238
239 pNewNode = m_pNodeHead;
240
241 if (1 == pos)
242 {
243 m_pNodeHead = m_pNodeHead->next;
244 goto Exit1;
245 }
246 for (int i = 1; i < pos; i++)
247 {
248 pTempNode = pNewNode;
249 pNewNode = pNewNode->next;
250 }
251
252 pTempNode->next = pNewNode->next;
253
254 Exit1:
255 delete pNewNode;
256 --m_nCount;
257 }
258
259 // void RemoveHead(); //删除头结点
260
261 template<typename T>
262 inline void Mylist<T>::RemoveHead()
263 {
264 ASSERT(0!=m_nCount);
265 RemoveAt(1);
266 }
267
268 //void RemoveTail(); //删除尾结点
269 template<typename T>
270 inline void Mylist<T>::RemoveTail()
271 {
272 ASSERT(0 != m_nCount);
273 RemoveAt(m_nCount);
274 }
275
276 //void RemoveAll(); //删除所有元素
277 template<typename T>
278 void Mylist<T>::RemoveAll()
279 {
280 //ASSERT(0 != m_nCount);
281
282 Node<T> *pNewNode;
283 Node<T> *pTempNode;
284
285 pNewNode = m_pNodeHead;
286 /* while (pNewNode)
287 {
288 pTempNode = pNewNode;
289 pNewNode = pTempNode->next;
290
291 m_nCount--;
292 delete pTempNode;
293 pTempNode = NULL;
294 }
295 */
296 for (int i = 0; i < m_nCount; i++)
297 {
298 pTempNode = pNewNode;
299 pNewNode = pTempNode->next;
300
301 delete pTempNode;
302 pTempNode = NULL;
303 }
304 m_nCount = 0;
305 }
306
307 //T& GetTail(); //获取尾元素引用
308 template<typename T>
309 T& Mylist<T>::GetTail()
310 {
311 ASSERT( 0 != m_nCount);
312
313 Node<T> *pNewNode;
314
315 pNewNode = m_pNodeHead;
316
317 for (int i = 1; i < m_nCount; i++)
318 {
319 pNewNode = pNewNode->next;
320 }
321
322 return pNewNode->data;
323 }
324
325 //T GetTail() const; //获取尾元素
326 template<typename T>
327 T Mylist<T>::GetTail() const
328 {
329 ASSERT(0 != m_nCount);
330
331 Node<T> *pNewNode;
332 pNewNode = m_pNodeHead;
333
334 for (int i = 1; i < m_nCount; i++)
335 {
336 pNewNode = pNewNode->next;
337 }
338
339 return pNewNode->data;
340 }
341
342 //T& GetHead(); //获取头结点引用
343 template<typename T>
344 T& Mylist<T>::GetHead()
345 {
346 ASSERT(0 != m_nCount);
347
348 return m_pNodeHead->data;
349 }
350
351 //T GetHead() const; //获取头结点
352 template<typename T>
353 T Mylist<T>::GetHead() const
354 {
355 ASSERT(0 != m_nCount);
356
357 return m_pNodeHead->data;
358 }
359
360 //T& GetAt(const int pos); //根据位置获取某元素引用
361 template<typename T>
362 T& Mylist<T>::GetAt(const int pos)
363 {
364 ASSERT(1 <= pos && pos <= m_nCount);
365
366 Node<T> *pNewNode;
367 pNewNode = m_pNodeHead;
368
369 for (int i = 1; i < m_nCount; i++)
370 {
371 pNewNode = pNewNode->next;
372 }
373
374 return pNewNode->data;
375
376 }
377
378 //T GetAt(const int pos) const; //根据位置获取某元素
379 template<typename T>
380 T Mylist<T>::GetAt(const int pos) const
381 {
382 ASSERT(1 <= pos && pos <= m_nCount);
383
384 Node<T> *pNewNode;
385 pNewNode = m_pNodeHead;
386
387 for (int i = 1; i < m_nCount; i++)
388 {
389 pNewNode = pNewNode->next;
390 }
391
392 return pNewNode->data;
393
394 }
395 //void SetAt(const int pos, T data); //修改特定位置的值
396 template<typename T>
397 void Mylist<T>::SetAt(const int pos, T data)
398 {
399 ASSERT(1 <= pos && pos <= m_nCount);
400
401 Node<T> *pNewNode;
402
403 pNewNode = m_pNodeHead;
404
405 for (int i = 1; i < pos; i++)
406 {
407 pNewNode = pNewNode->next;
408 }
409
410 pNewNode->data = data;
411 }
412
413 //int Find(const T data) const; //查找元素
414
415 template<typename T>
416 int Mylist<T>::Find(const T data) const
417 {
418 ASSERT(0 != m_nCount);
419
420 Node<T> *pNewNode;
421 int i = 1;
422
423 pNewNode = m_pNodeHead;
424
425 /* while (pNewNode)
426 {
427 i++;
428
429 if (pNewNode->data == data)
430 {
431 return i;
432 }
433 else
434 {
435 pNewNode = pNewNode->next;
436 }
437 }
438 */
439 for (i = 0; i < m_nCount; i++)
440 {
441 if (pNewNode->data == data)
442 {
443 return i+1;
444 }
445 pNewNode = pNewNode->next;
446 }
447 return -1;
448 }
449

 

posted @ 2010-07-11 17:34  Nermor  阅读(635)  评论(0)    收藏  举报