剑指offer——面试题18.1:删除链表中重复的节点
Posted acm-jing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer——面试题18.1:删除链表中重复的节点相关的知识,希望对你有一定的参考价值。
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. "); 71 else 72 printf("FAILED. "); 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 }
以上是关于剑指offer——面试题18.1:删除链表中重复的节点的主要内容,如果未能解决你的问题,请参考以下文章