1. // 面试题18(一):在O(1)时间删除链表结点
  2. // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
  3. // 结点。
  4.  
  5. #include <iostream>
  6. #include "List.h"
  7.  
  8. void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
  9. {
  10. if (!pListHead || !pToBeDeleted)
  11. return;
  12.  
  13. // 第一种情况:要删除的结点不是尾结点
  14. if (pToBeDeleted->m_pNext != nullptr)
  15. {
  16. ListNode* pNext = pToBeDeleted->m_pNext;//得到待删除节点的下一个节点
  17. pToBeDeleted->m_nValue = pNext->m_nValue;//将该节点的值和地址给覆盖待删除节点
  18. pToBeDeleted->m_pNext = pNext->m_pNext;
  19.  
  20. delete pNext;//删除这个替罪羊
  21. pNext = nullptr;
  22. }
  23. // 第二种情况:链表只有一个结点,删除头结点(也是尾结点)
  24. else if (*pListHead == pToBeDeleted)
  25. {
  26. delete pToBeDeleted;
  27. pToBeDeleted = nullptr;
  28. *pListHead = nullptr;//注意吧头结点置空
  29. }
  30. // 第三种情况:链表中有多个结点,删除尾结点
  31. else
  32. {
  33. ListNode* pNode = *pListHead;
  34. while (pNode->m_pNext != pToBeDeleted)//只能通过顺序查找并删除了
  35. {
  36. pNode = pNode->m_pNext;
  37. }
  38.  
  39. pNode->m_pNext = nullptr;
  40. delete pToBeDeleted;
  41. pToBeDeleted = nullptr;
  42. }
  43. }
  44.  
  45. // ====================测试代码====================
  46. void Test(ListNode* pListHead, ListNode* pNode)
  47. {
  48. printf("The original list is: \n");
  49. PrintList(pListHead);
  50.  
  51. printf("The node to be deleted is: \n");
  52. PrintListNode(pNode);
  53.  
  54. DeleteNode(&pListHead, pNode);//注意这个函数的输入
  55.  
  56. printf("The result list is: \n");
  57. PrintList(pListHead);
  58. }
  59.  
  60. // 链表中有多个结点,删除中间的结点
  61. void Test1()
  62. {
  63. ListNode* pNode1 = CreateListNode();
  64. ListNode* pNode2 = CreateListNode();
  65. ListNode* pNode3 = CreateListNode();
  66. ListNode* pNode4 = CreateListNode();
  67. ListNode* pNode5 = CreateListNode();
  68.  
  69. ConnectListNodes(pNode1, pNode2);
  70. ConnectListNodes(pNode2, pNode3);
  71. ConnectListNodes(pNode3, pNode4);
  72. ConnectListNodes(pNode4, pNode5);
  73.  
  74. Test(pNode1, pNode3);
  75.  
  76. DestroyList(pNode1);
  77. }
  78.  
  79. // 链表中有多个结点,删除尾结点
  80. void Test2()
  81. {
  82. ListNode* pNode1 = CreateListNode();
  83. ListNode* pNode2 = CreateListNode();
  84. ListNode* pNode3 = CreateListNode();
  85. ListNode* pNode4 = CreateListNode();
  86. ListNode* pNode5 = CreateListNode();
  87.  
  88. ConnectListNodes(pNode1, pNode2);
  89. ConnectListNodes(pNode2, pNode3);
  90. ConnectListNodes(pNode3, pNode4);
  91. ConnectListNodes(pNode4, pNode5);
  92.  
  93. Test(pNode1, pNode5);
  94.  
  95. DestroyList(pNode1);
  96. }
  97.  
  98. // 链表中有多个结点,删除头结点
  99. void Test3()
  100. {
  101. ListNode* pNode1 = CreateListNode();
  102. ListNode* pNode2 = CreateListNode();
  103. ListNode* pNode3 = CreateListNode();
  104. ListNode* pNode4 = CreateListNode();
  105. ListNode* pNode5 = CreateListNode();
  106.  
  107. ConnectListNodes(pNode1, pNode2);
  108. ConnectListNodes(pNode2, pNode3);
  109. ConnectListNodes(pNode3, pNode4);
  110. ConnectListNodes(pNode4, pNode5);
  111.  
  112. Test(pNode1, pNode1);
  113.  
  114. DestroyList(pNode1);
  115. }
  116.  
  117. // 链表中只有一个结点,删除头结点
  118. void Test4()
  119. {
  120. ListNode* pNode1 = CreateListNode();
  121.  
  122. Test(pNode1, pNode1);
  123. }
  124.  
  125. // 链表为空
  126. void Test5()
  127. {
  128. Test(nullptr, nullptr);
  129. }
  130.  
  131. int main(int argc, char* argv[])
  132. {
  133. Test1();
  134. Test2();
  135. Test3();
  136. Test4();
  137. Test5();
  138. system("pause");
  139. return ;
  140. }

《剑指offer》第十八题(在O(1)时间删除链表结点)的更多相关文章

  1. 剑指Offer面试题:12.在O(1)时间删除链表结点

    一.题目:在O(1)时间删除链表结点 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 原文采用的是C/C++,这里采用C#,节点定义如下: public class ...

  2. 【剑指offer 面试题13】在 O(1) 时间删除链表结点

    #include <iostream> using namespace std; //构造链表结点 struct ListNode { int val; ListNode *next; L ...

  3. (剑指Offer)面试题13:在O(1)时间内删除链表结点

    题目: 在给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间内删除该结点.链表结点与函数的定义如下: struct ListNode{ int val; ListNode* next; } ...

  4. 《剑指offer》面试题13 在O(1)时间删除链表节点 Java版

    这道题的关键是知道找到尾节点的前一个节点必须遍历,而且这样做了之后总的时间复杂度还是O(1),以及如何不破坏链表删除一个已知节点 public ListNode delete(ListNode hea ...

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

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

  6. 第18题:在O(1)时间删除链表结点+删除链表中重复的节点

    题目描述:题目描述在O(1)时间删除链表结点 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 考查创新编程能力. 思路: 1.如果从头到尾遍历,时间O(n) 2.如果将待删 ...

  7. 《剑指offer》第八题(重要!查找二叉树的中序遍历的下一个结点)

    文件一:main.cpp // 面试题:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有 ...

  8. 剑指offer五十八之对称的二叉树

    一.题目 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的.二.思路 递归做,详见代码 三.代码 /* public class TreeN ...

  9. 剑指offer四十八之不用加减乘除做加法

    一.题目 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 二.思路 1. 采用位运算的方法,分三步: (1).两个数异或:相当于每一位相加,而不考虑进位 (2).两个数 ...

  10. 剑指offer二十八之数组中出现次数超过一半的数字

    一.题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

随机推荐

  1. python 多进程并发接口测试实例

    #encoding=utf-8 import requests import json import os import hashlib print "register------" ...

  2. Linux服务器配置---ftp用户黑名单

    用户黑白名单 一个Linux主机中会多个用户,而我们希望有些用户不能去访问ftp.ftp服务器可以通过配置文件“/etc/vsftpd/user_list”来设置一个用户列表,这个列表可以是黑名单,也 ...

  3. Linux学习笔记之passwd:Authentication token manipulation error_错误的解决办法

    如果在linux中,不管是root用户还是普通用户登录后,修改自己的密码,出现—passwd:Authentication token manipulation error—错误的解决办法: root ...

  4. Python入门之用Python统计代码行

    Pycharm每天都要写很多代码,如何统计每天的代码行数呢?作为一个目标十万行的coder,要想想办法! 题目:有个目录,里面是你自己写过的程序,统计一下你写过多少行代码.包括空行和注释,但是要分别列 ...

  5. P2503 [HAOI2006]均分数据

    P2503 [HAOI2006]均分数据 模拟退火+dp (不得不说,我今天欧气爆棚) 随机出1个数列,然后跑一遍dp统计 #include<iostream> #include<c ...

  6. Mysql的基本语句

    Mysql的基本语句 1.查询当前数据库所有表名: -- 方案一: show tables; --方案二:jeesite为数据库 select table_name from information_ ...

  7. 20145122 《Java程序设计》第8周学习总结

    教材学习内容总结 1.NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),rewind(),flip(),compact()等高级操作. 2.想要取得channel的操 ...

  8. msf辅助模块的应用——20145301

    msf辅助模块的应用 实验步骤 创建msf所需的数据库 service postgresql start msfdb start 开启msf,输入命令 use auxiliary/scanner/di ...

  9. 20145313张雪纯MSF基础应用实验

    实验博客 ms08_067攻击实验 http://www.cnblogs.com/entropy/p/6690301.html ms11_050漏洞攻击 http://www.cnblogs.com/ ...

  10. noip 瑞士轮 - 归并

    背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长 ...