1 // LinkListDemo.cpp : Defines the entry point for the console application.
2 //
3
4 #include "stdafx.h"
5
6 #include <iostream>
7 #include <assert.h>
8 using namespace std;
9
10 #define random(x) (rand()%x)
11
12 #define INVALIDVALUE -1000000000
13
14 typedef struct LNode
15 {
16 int data;
17 LNode* pnext;
18 LNode(){data = INVALIDVALUE; pnext = NULL;}
19 }BINODE, *PBINODE;
20
21 class CLinkList
22 {
23 public:
24 CLinkList();
25 ~CLinkList();
26
27 private:
28 CLinkList(const CLinkList &rh);
29 CLinkList& operator=(const CLinkList &rh);
30
31 public:
32
33 //
34 // 函数功能:获取链表中元素个数
35 int getcount();
36
37 //
38 // 函数功能:清空链表
39 void clear();
40
41 //
42 // 函数功能:获取链表第nPos个位置上的结点指针
43 PBINODE getnode(int nPos);
44
45 //
46 // 函数功能:获取中间结点
47 // 注:这个获取的方式是通过连个指针,一个步长为1,另一个步长为2.步长为2的走到底后步长为1的正好到中间
48 int getmid();
49
50 //
51 // 函数功能:获取根结点
52 PBINODE getroot();
53
54 //
55 // 函数功能:在nPos位置上插入元素
56 bool insertnode(PBINODE pNode, int nPos);
57
58 //
59 // 函数功能:在nPos位置上插入元素
60 bool insertnode(int value, int nPos);
61
62 //
63 // 函数功能:删除第nPos位置上的元素
64 bool deletenode(int nPos);
65
66 //
67 // 函数功能:打印链表
68 void printnode();
69
70 //
71 // 函数功能:值为nValue元素的第n次出现的位置
72 int locate(int nvalue,int n);
73
74 //
75 // 函数功能:逆置
76 void reverse();
77
78 //
79 // 函数功能:排序(冒泡排序法)
80 void BubbleSort();
81
82 private:
83 PBINODE m_root;
84 int m_nCount;
85 };
86
87 CLinkList::CLinkList()
88 {
89 m_root = new LNode();
90 m_nCount = 0;
91 assert(m_root != NULL);
92 }
93
94 CLinkList::~CLinkList()
95 {
96 clear();
97 }
98
99 //
100 // 函数功能:获取链表中元素个数
101 int CLinkList::getcount()
102 {
103 return m_nCount;
104 }
105
106 //
107 // 函数功能:清空链表
108 void CLinkList::clear()
109 {
110 PBINODE pNode = m_root;
111 PBINODE ptmpNode = NULL;
112 while(pNode != NULL)
113 {
114 ptmpNode = pNode->pnext;
115 delete pNode;
116 pNode = ptmpNode;
117 }
118 m_root = NULL;
119 }
120
121 //
122 // 函数功能:获取根结点
123 PBINODE CLinkList::getroot()
124 {
125 return m_root;
126 }
127
128 //
129 // 函数功能:获取链表第nPos个位置上的结点指针
130 PBINODE CLinkList::getnode(int npos)
131 {
132 if (m_root == NULL)
133 {
134 return NULL;
135 }
136
137 if (npos > getcount())
138 {
139 return NULL;
140 }
141
142 PBINODE pNode = m_root;
143 int i = 0;
144 while (i < npos)
145 {
146 pNode = pNode->pnext;
147 i++;
148 }
149 return pNode;
150 }
151
152 //
153 // 函数功能:获取中间结点
154 // 注:这个获取的方式是通过连个指针,一个步长为1,另一个步长为2.步长为2的走到底后步长为1的正好到中间
155 int CLinkList::getmid()
156 {
157 /*
158 // 方法一,通过对象本身的个数来求中间的元素
159 if (getcount() <= 1)
160 {
161 return INVALIDVALUE;
162 }
163
164 int nMid = getcount() / 2;
165
166 PBINODE pNode = getnode(nMid);
167 assert(pNode != NULL);
168
169 return pNode->data;
170 */
171
172 PBINODE pNode = getroot();
173 PBINODE pTNode = pNode->pnext;
174 while (pTNode != NULL)
175 {
176 pNode = pNode->pnext;
177 pTNode = pTNode->pnext;
178 if (pTNode != NULL)
179 {
180 pTNode = pTNode->pnext;
181 }
182 }
183 assert(pNode != NULL);
184 return pNode->data;
185 }
186
187 //
188 // 函数功能:在nPos位置上插入元素
189 bool CLinkList::insertnode(PBINODE pNode, int nPos)
190 {
191 if (pNode == NULL || nPos <= 0 || nPos > getcount() + 1)
192 {
193 return false;
194 }
195
196 PBINODE pPreNode = getnode(nPos - 1);
197 assert(pPreNode != 0);
198 PBINODE ptmp = pPreNode->pnext;
199 pPreNode->pnext = pNode;
200 pNode->pnext = ptmp;
201 m_nCount++;
202
203 return true;
204 }
205
206 //
207 // 函数功能:在nPos位置上插入元素
208 bool CLinkList::insertnode(int value, int nPos)
209 {
210 if (nPos <= 0 || nPos > getcount() + 1)
211 {
212 return false;
213 }
214
215 PBINODE pNode = new LNode();
216 assert(pNode != NULL);
217 pNode->data = value;
218
219 PBINODE pPreNode = getnode(nPos - 1);
220 assert(pPreNode != NULL);
221
222 PBINODE ptmp = pPreNode->pnext;
223
224 pPreNode->pnext = pNode;
225 pNode->pnext = ptmp;
226
227 m_nCount++;
228
229 return true;
230 }
231
232 //
233 // 函数功能:删除第nPos位置上的元素
234 bool CLinkList::deletenode(int nPos)
235 {
236 if (nPos <= 0 || nPos > getcount())
237 {
238 return false;
239 }
240
241 PBINODE pNode = getnode(nPos - 1);
242 assert(pNode != NULL);
243 PBINODE pDNode = pNode->pnext;
244 assert(pDNode != NULL);
245 pNode->pnext = pDNode->pnext;
246
247 delete pDNode;
248 pDNode = NULL;
249
250 return true;
251 }
252
253 //
254 // 函数功能:打印链表
255 void CLinkList::printnode()
256 {
257 PBINODE root = getroot();
258 PBINODE pNode = root->pnext;
259 while(pNode != NULL)
260 {
261 cout<< pNode->data<< " ";
262 pNode = pNode->pnext;
263 }
264 cout<<endl;
265 }
266
267 //
268 // 函数功能:值为nValue元素的第n次出现的位置
269 int CLinkList::locate(int nvalue,int n)
270 {
271 PBINODE root = getroot();
272 PBINODE pNode = root->pnext;
273 int i = 0;
274
275 int nNum = 0;
276 while (pNode != NULL /*&& pNode->data != nvalue*/)
277 {
278 if (pNode->data == nvalue)
279 {
280 nNum++;
281 }
282 pNode = pNode->pnext;
283 i++;
284 if (nNum == n)
285 {
286 break;
287 }
288 }
289
290 if (pNode == NULL)
291 {
292 return 0;
293 }
294 else
295 {
296 return i;
297 }
298
299 }
300
301 //
302 // 函数功能:逆置
303 void CLinkList::reverse()
304 {
305 PBINODE root = getroot();
306 assert(root != NULL);
307
308 PBINODE prenode = root->pnext;
309 assert(prenode != NULL);
310
311 PBINODE curnode = prenode->pnext;
312 prenode->pnext = NULL;
313 while (curnode != NULL)
314 {
315 PBINODE nextnode = curnode->pnext;
316 curnode->pnext = prenode;
317 prenode = curnode;
318 curnode = nextnode;
319 }
320
321 root->pnext = prenode;
322 }
323
324 //
325 // 函数功能:排序(冒泡排序法)
326 void CLinkList::BubbleSort()
327 {
328 PBINODE root = getroot();
329 assert(root != NULL);
330
331 for (int i = 0; i < getcount(); i++)
332 {
333 PBINODE pNode = root->pnext;
334 for (int j = 0; j < getcount() - i; j++)
335 {
336 PBINODE pNodeNext = pNode->pnext;
337 if (pNodeNext == NULL)
338 {
339 break;
340 }
341 if (pNode->data > pNodeNext->data)
342 {
343 int tmp = pNode->data;
344 pNode->data = pNodeNext->data;
345 pNodeNext->data = tmp;
346 }
347 pNode = pNode->pnext;
348 if (pNode == NULL)
349 {
350 break;
351 }
352 }
353 }
354 }
355
356 //已知指针la和lb分别指向两个链表。下列算法是从表la中删除自第i个元素起共len个元素后,将它们插入到表lb中第i个元素之前。
357 void DeleteAndInsertSub(CLinkList &la, CLinkList &lb, int i, int len)
358 {
359 if (i + len - 1 > la.getcount() || i <= 0 || len < 0 || i > lb.getcount())
360 {
361 return;
362 }
363
364 if (la.getroot() == lb.getroot())
365 {
366 return;
367 }
368
369 PBINODE pLa = la.getnode(i);
370 if (pLa == NULL)
371 {
372 return;
373 }
374
375 int nCount = 0;
376 while (nCount < len && pLa != NULL)
377 {
378 int nvalue = pLa->data;
379 lb.insertnode(nvalue, i + nCount);
380 pLa = pLa->pnext;
381 nCount++;
382 }
383 }
384
385 //已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序
386 void Merge(CLinkList &la, CLinkList &lb)
387 {
388
389 }
390
391 //如何检查一个单向链表上是否有环,同样两个指针,一个步长为1,另一个步长为2,如果两个指针能相遇则有环。
392 bool IsCircle(const CLinkList &la)
393 {
394
395 }
396
397 //只给定单链表中某个结点p(并非最后一个结点,即p->next!=NULL)指针,删除该结点。将p后面那个节点的值复制到p,删除p后面的节点
398 void DeleteNode(int nPos)
399 {
400
401 }
402
403 //在p前面插入一个节点 。在p后面插入新节点,将p的值与新建的节点值互换。
404 void InsertNode(int nPos)
405 {
406
407 }
408
409 //给定单链表头结点,删除链表中倒数第k个结点. 一个指针指向链表头,另一个指针指向第k个指针,然后两个指针一起移动,第二个指针到了末端则第一个指针就是倒数第k个节点
410 void ReverseDelete(int npos)
411 {
412
413 }
414
415 //判断两个链表是否相交。两种情况,如果链表有环,则先在环里设定一个指针不动,另一个链表从头开始移动,如果另一个链表能够与环中的指针相遇则是相交。如果没有环,则判断两个链表的最后个节点是否相同,相同则相交
416 bool IsCross(const CLinkList &la, const CLinkList &lb)
417 {
418
419 }
420
421 //两个链表相交,找出交点求出两个链表的长度a和b,一个指针指向较短链表的头head,另一个指针指向较长链表的第head+|a-b|,然后两个指针一起移动,相遇处即为交点。
422 int CrossNode(const CLinkList &la, const CLinkList &lb)
423 {
424
425 }
426
427 int _tmain(int argc, _TCHAR* argv[])
428 {
429 CLinkList link1;
430
431 cout<<"初始化链表link1:"<<endl;
432 int i = 0;
433 for (i = 1; i <= 15; i++)
434 {
435 int val = random(100);
436 if (!link1.insertnode(val, i))
437 {
438 return 0;
439 }
440 }
441
442 link1.insertnode(41, 10);
443 link1.printnode();
444 cout<<"link1链表长度为:"<<link1.getcount()<<endl;
445 cout << "41在link1中第2次出现的位置:"<<link1.locate(41, 2)<<endl;
446 cout<<"link1链表逆序为:"<<endl;
447 link1.reverse();
448 link1.printnode();
449 cout<<endl;
450
451 CLinkList link2;
452 cout<<"初始化链表link2:"<<endl;
453 for (i = 1; i <= 20; i++)
454 {
455 int val = random(100);
456 if (!link2.insertnode(val, i))
457 {
458 return 0;
459 }
460 }
461 link2.insertnode(41, 17);
462 link2.printnode();
463 cout<<"link2链表长度为:"<<link2.getcount()<<endl;
464
465 DeleteAndInsertSub(link1, link2, 3, 3);
466 link2.printnode();
467 cout<<"修改后link2链表长度为:"<<link2.getcount()<<endl;
468
469 cout<<endl<<"两个链表进行排序,排序后显示:"<<endl;
470 link1.BubbleSort();
471 link1.printnode();
472
473 link2.BubbleSort();
474 link2.printnode();
475
476 cout<<"获取link1的中间元素:";
477 cout<<link1.getmid()<<endl;
478 return 0;
479 }