1 // 面试题18(二):删除链表中重复的结点
2 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复
3 // 结点被删除之后,链表如图3.4(b)所示。
4
5 #include <cstdio>
6 #include "List.h"
7
8 void DeleteDuplication(ListNode** pHead)
9 {
10 if(pHead == nullptr || *pHead == nullptr)
11 return;
12
13 ListNode* pPreNode = nullptr;
14 ListNode* pNode = *pHead;
15 while(pNode != nullptr)
16 {
17 ListNode *pNext = pNode->m_pNext;
18 bool needDelete = false;
19 if(pNext != nullptr && pNext->m_nValue == pNode->m_nValue)
20 needDelete = true;
21
22 if(!needDelete)
23 {
24 pPreNode = pNode;
25 pNode = pNode->m_pNext;
26 }
27 else
28 {
29 int value = pNode->m_nValue;
30 ListNode* pToBeDel = pNode;
31 while(pToBeDel != nullptr && pToBeDel->m_nValue == value)
32 {
33 pNext = pToBeDel->m_pNext;
34
35 delete pToBeDel;
36 pToBeDel = nullptr;
37
38 pToBeDel = pNext;
39 }
40
41 if(pPreNode == nullptr)
42 *pHead = pNext;
43 else
44 pPreNode->m_pNext = pNext;
45 pNode = pNext;
46 }
47 }
48 }
49
50 // ====================测试代码====================
51 void Test(char* testName, ListNode** pHead, int* expectedValues, int expectedLength)
52 {
53 if(testName != nullptr)
54 printf("%s begins: ", testName);
55
56 DeleteDuplication(pHead);
57
58 int index = 0;
59 ListNode* pNode = *pHead;
60 while(pNode != nullptr && index < expectedLength)
61 {
62 if(pNode->m_nValue != expectedValues[index])
63 break;
64
65 pNode = pNode->m_pNext;
66 index++;
67 }
68
69 if(pNode == nullptr && index == expectedLength)
70 printf("Passed.\n");
71 else
72 printf("FAILED.\n");
73 }
74
75 // 某些结点是重复的
76 void Test1()
77 {
78 ListNode* pNode1 = CreateListNode(1);
79 ListNode* pNode2 = CreateListNode(2);
80 ListNode* pNode3 = CreateListNode(3);
81 ListNode* pNode4 = CreateListNode(3);
82 ListNode* pNode5 = CreateListNode(4);
83 ListNode* pNode6 = CreateListNode(4);
84 ListNode* pNode7 = CreateListNode(5);
85
86 ConnectListNodes(pNode1, pNode2);
87 ConnectListNodes(pNode2, pNode3);
88 ConnectListNodes(pNode3, pNode4);
89 ConnectListNodes(pNode4, pNode5);
90 ConnectListNodes(pNode5, pNode6);
91 ConnectListNodes(pNode6, pNode7);
92
93 ListNode* pHead = pNode1;
94
95 int expectedValues[] = { 1, 2, 5 };
96 Test("Test1", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
97
98 DestroyList(pHead);
99 }
100
101 // 没有重复的结点
102 void Test2()
103 {
104 ListNode* pNode1 = CreateListNode(1);
105 ListNode* pNode2 = CreateListNode(2);
106 ListNode* pNode3 = CreateListNode(3);
107 ListNode* pNode4 = CreateListNode(4);
108 ListNode* pNode5 = CreateListNode(5);
109 ListNode* pNode6 = CreateListNode(6);
110 ListNode* pNode7 = CreateListNode(7);
111
112 ConnectListNodes(pNode1, pNode2);
113 ConnectListNodes(pNode2, pNode3);
114 ConnectListNodes(pNode3, pNode4);
115 ConnectListNodes(pNode4, pNode5);
116 ConnectListNodes(pNode5, pNode6);
117 ConnectListNodes(pNode6, pNode7);
118
119 ListNode* pHead = pNode1;
120
121 int expectedValues[] = { 1, 2, 3, 4, 5, 6, 7 };
122 Test("Test2", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
123
124 DestroyList(pHead);
125 }
126
127 // 除了一个结点之外其他所有结点的值都相同
128 void Test3()
129 {
130 ListNode* pNode1 = CreateListNode(1);
131 ListNode* pNode2 = CreateListNode(1);
132 ListNode* pNode3 = CreateListNode(1);
133 ListNode* pNode4 = CreateListNode(1);
134 ListNode* pNode5 = CreateListNode(1);
135 ListNode* pNode6 = CreateListNode(1);
136 ListNode* pNode7 = CreateListNode(2);
137
138 ConnectListNodes(pNode1, pNode2);
139 ConnectListNodes(pNode2, pNode3);
140 ConnectListNodes(pNode3, pNode4);
141 ConnectListNodes(pNode4, pNode5);
142 ConnectListNodes(pNode5, pNode6);
143 ConnectListNodes(pNode6, pNode7);
144
145 ListNode* pHead = pNode1;
146
147 int expectedValues[] = { 2 };
148 Test("Test3", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
149
150 DestroyList(pHead);
151 }
152
153 // 所有结点的值都相同
154 void Test4()
155 {
156 ListNode* pNode1 = CreateListNode(1);
157 ListNode* pNode2 = CreateListNode(1);
158 ListNode* pNode3 = CreateListNode(1);
159 ListNode* pNode4 = CreateListNode(1);
160 ListNode* pNode5 = CreateListNode(1);
161 ListNode* pNode6 = CreateListNode(1);
162 ListNode* pNode7 = CreateListNode(1);
163
164 ConnectListNodes(pNode1, pNode2);
165 ConnectListNodes(pNode2, pNode3);
166 ConnectListNodes(pNode3, pNode4);
167 ConnectListNodes(pNode4, pNode5);
168 ConnectListNodes(pNode5, pNode6);
169 ConnectListNodes(pNode6, pNode7);
170
171 ListNode* pHead = pNode1;
172
173 Test("Test4", &pHead, nullptr, 0);
174
175 DestroyList(pHead);
176 }
177
178 // 所有结点都成对出现
179 void Test5()
180 {
181 ListNode* pNode1 = CreateListNode(1);
182 ListNode* pNode2 = CreateListNode(1);
183 ListNode* pNode3 = CreateListNode(2);
184 ListNode* pNode4 = CreateListNode(2);
185 ListNode* pNode5 = CreateListNode(3);
186 ListNode* pNode6 = CreateListNode(3);
187 ListNode* pNode7 = CreateListNode(4);
188 ListNode* pNode8 = CreateListNode(4);
189
190 ConnectListNodes(pNode1, pNode2);
191 ConnectListNodes(pNode2, pNode3);
192 ConnectListNodes(pNode3, pNode4);
193 ConnectListNodes(pNode4, pNode5);
194 ConnectListNodes(pNode5, pNode6);
195 ConnectListNodes(pNode6, pNode7);
196 ConnectListNodes(pNode7, pNode8);
197
198 ListNode* pHead = pNode1;
199
200 Test("Test5", &pHead, nullptr, 0);
201
202 DestroyList(pHead);
203 }
204
205 // 除了两个结点之外其他结点都成对出现
206 void Test6()
207 {
208 ListNode* pNode1 = CreateListNode(1);
209 ListNode* pNode2 = CreateListNode(1);
210 ListNode* pNode3 = CreateListNode(2);
211 ListNode* pNode4 = CreateListNode(3);
212 ListNode* pNode5 = CreateListNode(3);
213 ListNode* pNode6 = CreateListNode(4);
214 ListNode* pNode7 = CreateListNode(5);
215 ListNode* pNode8 = CreateListNode(5);
216
217 ConnectListNodes(pNode1, pNode2);
218 ConnectListNodes(pNode2, pNode3);
219 ConnectListNodes(pNode3, pNode4);
220 ConnectListNodes(pNode4, pNode5);
221 ConnectListNodes(pNode5, pNode6);
222 ConnectListNodes(pNode6, pNode7);
223 ConnectListNodes(pNode7, pNode8);
224
225 ListNode* pHead = pNode1;
226
227 int expectedValues[] = { 2, 4 };
228 Test("Test6", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
229
230 DestroyList(pHead);
231 }
232
233 // 链表中只有两个不重复的结点
234 void Test7()
235 {
236 ListNode* pNode1 = CreateListNode(1);
237 ListNode* pNode2 = CreateListNode(2);
238
239 ConnectListNodes(pNode1, pNode2);
240
241 ListNode* pHead = pNode1;
242
243 int expectedValues[] = { 1, 2 };
244 Test("Test7", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
245
246 DestroyList(pHead);
247 }
248
249 // 结点中只有一个结点
250 void Test8()
251 {
252 ListNode* pNode1 = CreateListNode(1);
253
254 ConnectListNodes(pNode1, nullptr);
255
256 ListNode* pHead = pNode1;
257
258 int expectedValues[] = { 1 };
259 Test("Test8", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
260
261 DestroyList(pHead);
262 }
263
264 // 结点中只有两个重复的结点
265 void Test9()
266 {
267 ListNode* pNode1 = CreateListNode(1);
268 ListNode* pNode2 = CreateListNode(1);
269
270 ConnectListNodes(pNode1, pNode2);
271
272 ListNode* pHead = pNode1;
273
274 Test("Test9", &pHead, nullptr, 0);
275
276 DestroyList(pHead);
277 }
278
279 // 空链表
280 void Test10()
281 {
282 ListNode* pHead = nullptr;
283
284 Test("Test10", &pHead, nullptr, 0);
285 }
286
287 int main(int argc, char* argv[])
288 {
289 Test1();
290 Test2();
291 Test3();
292 Test4();
293 Test5();
294 Test6();
295 Test7();
296 Test8();
297 Test9();
298 Test10();
299
300 return 0;
301 }