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

《剑指offer》第十八题(删除链表中重复的结点)的更多相关文章

  1. 剑指offer五十六之删除链表中重复的结点

    一.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  2. 【校招面试 之 剑指offer】第18题 删除链表中的节点

    题目一:在O(1)时间内删除链表节点. 给定单项链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点. 思路:(1)如果要删除的节点不是链表的尾节点,则将被删除节点的内容复制到该节点,然 ...

  3. 《剑指offer》第二十三题(链表中环的入口结点)

    // 面试题23:链表中环的入口结点 // 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, // 环的入口结点是结点3. #include <iostream> ...

  4. 剑指Offer(十八):二叉树的镜像

    剑指Offer(十八):二叉树的镜像 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu ...

  5. 【Java】 剑指offer(18) 删除链表中重复的结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重 ...

  6. 【剑指Offer】删除链表中重复的结点 解题报告(Python)

    [剑指Offer]删除链表中重复的结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interview ...

  7. leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点)

    203题是在链表中删除一个固定的值,83题是在链表中删除重复的数值,但要保留一个:82也是删除重复的数值,但重复的都删除,不保留. 比如[1.2.2.3],83题要求的结果是[1.2.3],82题要求 ...

  8. 剑指offer-18-2. 删除链表中重复的结点

    剑指offer-18-2. 删除链表中重复的结点 链表 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3-> ...

  9. [PHP] 算法-删除链表中重复的结点的PHP实现

    删除链表中重复的结点: 1.定义两个指针pre和current 2.两个指针同时往后移动,current指针如果与后一个结点值相同,就独自往前走直到没有相等的 3.pre指针next直接指向curre ...

随机推荐

  1. 用python写http接口自动化测试框架

    本文是转载张元礼的博客 http://blog.csdn.Net/vincetest 一.测试需求描述 对服务后台一系列的http接口功能测试. 输入:根据接口描述构造不同的参数输入值 输出:XML文 ...

  2. Java中将xml文件转化为json的两种方式

    原文地址https://blog.csdn.net/a532672728/article/details/76312475 最近有个需求,要将xml转json之后存储在redis中,找来找去发现整体来 ...

  3. JQuery中如何使用事件来出发Ajax

    $(document).ready(function(){                $("input[name='customer_name']").keydown(func ...

  4. linux make configure make

    开放源码:就是程序代码,写给人类看的程序语言,但机器并不认识,所以无法执行: 编译程序:将程序代码转译成为机器看得懂的语言,就类似编译者的角色: 可执行文件:经过编译程序变成二进制后机器看得懂所以可以 ...

  5. AO中的空间关系

    名词解释: Boundary(边界): 只有线和面才有边界.面的边界是指组成面的框架线:线的边界是指线的二个端点(即起点和终点,不包括中间部分的节点):点没有边界. Interior(内部): 除去边 ...

  6. 【VS Hacks】定制VS

    # Hack 24   定制快捷键 VS能够做很多键盘的配置,其实在VS中目前已经发现有很多的快捷键了,但是在这个技巧篇里会学到如何创建新的快捷键,以及编辑已有的快捷键.VS中包含很多的命令,只有其中 ...

  7. 2018-2019-2 20165209 《网络对抗技术》Exp4:恶意代码分析

    2018-2019-2 20165209 <网络对抗技术>Exp4:恶意代码分析 1 基础问题回答和实验内容 1.1基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监 ...

  8. Linux服务器---基础设置

    Centos分辨率      virtualbox里新安装的Centos 7 的分辨率默认的应该是800*600. 如果是‘最小化安装’的Centos7 进入的就是命令模式 .如果安装的是带有GUI的 ...

  9. 【JavaScript】数组随机排序 之 Fisher–Yates 洗牌算法

    Fisher–Yates随机置乱算法也被称做高纳德置乱算法,通俗说就是生成一个有限集合的随机排列.Fisher-Yates随机置乱算法是无偏的,所以每个排列都是等可能的,当前使用的Fisher-Yat ...

  10. 50个CSS技巧

    这里我工作中收集了10个很不错的CSS技巧,你可以用在你的项目上.它可以帮你很好地整理你的元素并让他们看起来蛮酷的.下面开始我们的内容,希望你会喜欢它.下面是我收集的CSS技巧,希望能帮助到你,感觉收 ...