【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第二章中“删除链表的中间节点和a/b处节点”这一题目的C++复现。

  本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。

  感谢左程云老师的支持。

【题目】:

  给定链表的头节点 head,实现删除链表的中间节点的函数。

  例如:

  步删除任何节点;

  1->2,删除节点1;

  1->2->3,删除节点2;

  1->2->3->4,删除节点2;

  1->2->3->4-5,删除节点3;

【进阶】:

  给定链表的头节点 head、整数 a 和 b,实现删除位于 a/b 处节点的函数。

  例如:

  链表:1->2->3->4->5,假设 a/b 的值为 r。

  如果 r = 0,不删除任何节点;

  如果 r 在区间 (0,1/5] 上,删除节点 1;

  如果 r 在区间 (1/5,2/5] 上,删除节点 2;

  如果 r 在区间 (2/5,3/5] 上,删除节点 3;

  如果 r 在区间 (3/5,4/5] 上,删除节点 4;

  如果 r 在区间 (4/5,1] 上,删除节点 5;

  如果 r 大于 1,不删除任何节点。

【思路】:

  对于删除中间节点的问题:设定两个指针,一个指针每次向前走一步,另一个向前走两步

  对于删除 a/b 节点问题:将小数区间转变为待删除节点的整数位置。

【编译环境】:

  CentOS6.7(x86_64)

  gcc 4.4.7

【实现】:

  实现及测试代码:

  1. /*
  2. *文件名:lists_remove.cpp
  3. *作者:
  4. *摘要:实现删除链表的中间节点和 a/b 处的节点
  5. */
  6. #include <iostream>
  7. #include <math.h>
  8.  
  9. using namespace std;
  10.  
  11. struct Node
  12. {
  13. int value;
  14. Node *next;
  15. };
  16.  
  17. //删除中间节点
  18. Node* removeMidNode(Node *head)
  19. {
  20. if(NULL == head || NULL == head->next)
  21. return head;
  22.  
  23. if(NULL == head->next->next)
  24. {
  25. Node *ptr = head;
  26. head = head->next;
  27. delete ptr;
  28. }
  29.  
  30. Node *pre = head;
  31. Node *cur = head->next->next;
  32. //找到待删除的中间节点的前一个(非双向链表)节点
  33. while(NULL != cur->next && NULL != cur->next->next)
  34. {
  35. pre = pre->next;
  36. cur = cur->next->next;
  37. }
  38. //将cur用作辅助指针
  39. cur = pre->next;
  40. pre->next = pre->next->next;
  41. delete cur;
  42. return head;
  43. }
  44.  
  45. //进阶问题,删除 a/b 节点
  46. Node* removeByRatio(Node *head,int a,int b)
  47. {
  48. if(a < || a > b)
  49. return head;
  50. int n = ;
  51. Node *cur = head;
  52.  
  53. while(NULL != cur) //统计链表中节点个数->n
  54. {
  55. n++;
  56. cur = cur->next;
  57. }
  58. //由小数区间转化为整数,这是本题最有技巧的地方
  59. n = (int)ceil( ((double) (a*n)) / ((double) b) );
  60.  
  61. if( == n)
  62. {
  63. cur = head;
  64. head = head->next;
  65. delete cur;
  66. }
  67.  
  68. if( < n)
  69. {
  70. cur = head;
  71. while( --n != ) //找到待删除节点的前一个节点
  72. cur = cur->next;
  73. Node *ptr = cur->next;
  74. cur->next = cur->next->next;
  75. delete ptr;
  76. }
  77. return head;
  78. }
  79.  
  80. //打印链表内容
  81. void printLists(Node *head)
  82. {
  83. while(NULL != head)
  84. {
  85. cout << head->value << " " ;
  86. head = head->next;
  87. }
  88. cout << endl;
  89. }
  90.  
  91. int main()
  92. {
  93. Node *head = NULL;
  94. Node *ptr = NULL;
  95.  
  96. for(int i =;i<;i++)//构造链表
  97. {
  98. if(NULL == head)
  99. {
  100. head = new Node;
  101. head->value = i;
  102. head->next = NULL;
  103. ptr = head;
  104. continue;
  105. }
  106. ptr->next = new Node;
  107. ptr = ptr->next;
  108. ptr->value = i;
  109. ptr->next = NULL;
  110. }
  111.  
  112. cout << "Before remove mid: " << endl;
  113. printLists(head);
  114. head = removeMidNode(head);
  115. cout << "After remove mid: " << endl;
  116. printLists(head);
  117.  
  118. int a(),b();
  119. cout << "Before remove "<< a << "/" << b << ": "<< endl;
  120. printLists(head);
  121. head = removeByRatio(head,a,b);
  122. cout << "After remove "<< a << "/" << b << ": "<< endl;
  123. printLists(head);
  124.  
  125. return ;
  126. }

注:

  转载请注明出处;

  转载请注明源思路来自于左程云老师的《程序员代码面试指南》。

删除链表的中间节点和a/b处节点的更多相关文章

  1. 《程序员代码面试指南》第二章 链表问题 删除中间节点和a/b处节点

    题目 例如 1-2-3-4 删除2,1-2-3-4-5 删除3 例如 a=1,b =2 java代码 /** * @Description:删除中间节点和a/b处节点 * @Author: lizho ...

  2. 数据结构:DHUOJ 删除链表的顺数及倒数第N个节点

    删除链表的顺数及倒数第N个节点 作者: turbo时间限制: 1S章节: DS:数组和链表 题目描述: 可使用以下代码,完成其中的removeNth函数,其中形参head指向无头结点单链表,n为要删除 ...

  3. 删除链表中等于给定值val的所有节点。

    样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5. /** * D ...

  4. 【leetcode 简单】 第五十七题 删除链表中的节点

    删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4 ...

  5. LeetCode:删除链表中的节点【203】

    LeetCode:删除链表中的节点[203] 题目描述 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val ...

  6. lintcode:删除链表中指定元素

    题目 删除链表中等于给定值val的所有节点. 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1-> ...

  7. 动图:删除链表的倒数第 N 个结点

    本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点.采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组. 19. 删除链表的倒 ...

  8. [LeetCode] Delete Node in a Linked List 删除链表的节点

    Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...

  9. [CareerCup] 2.3 Delete Node in a Linked List 删除链表的节点

    2.3 Implement an algorithm to delete a node in the middle of a singly linked list, given only access ...

随机推荐

  1. 轻轻谈一下seaJs——模块化开发的利器

    "仅做一件事,做好一件事." 这个应该就是seaJs的精髓了. 我在自己的一些项目中使用过seaJs.对其算是了解一二.如今就班门弄斧.轻轻地谈一下. 首先上一段度娘的话: &qu ...

  2. Android版xx助手之天天酷跑外挂具体分析

    Android版xx助手之天天酷跑外挂具体分析 图/文      莫灰灰 背景 近些年来,移动互联网的大肆崛起,潜移默化中影响着人们的生活和工作习惯.当腾讯的微信平台接入手机游戏之后,移动端的游戏也開 ...

  3. LeetCode总结 -- 高精度篇

    我们常见的一些主要的数据结构比方整型int或者浮点型float由于位数过多无法用内置类型存储,这时候我们就须要自己实现高精度的数据类型来进行存储和运算.这样的问题在实际产品中还是比較有用的,所以相对来 ...

  4. 最新版SDWebImage的使用

    我之前写过一篇博客,介绍缓存处理的三种方式,其中最难,最麻烦,最占内存资源的还是图片缓存,最近做的项目有大量的图片处理,还是采用了SDWebImage来处理,但是发现之前封装好的代码报错了.研究发现, ...

  5. linq中的cast<T>()及OfType<T>()

    DataTable dt=...........//获取从数据库中取出的数据(假设只有一条记录) //Cast<T>()用来将非泛型的序列转换为泛型的序列 DataRow row=dt.R ...

  6. Csharp多态的实现(虚方法)

    1.什么是抽象类 1.1虚方法是用virtual修饰,在子类中用override进行重写 1.2虚方法是一个方法,放在类里面(可以再下面的代码中看到) 1.3虚方法可以 重写,也可以不重写(这个可以再 ...

  7. [Jobdu] 题目1506:求1+2+3+...+n

    题目描述: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C).  输入: 输入可能包含多个测试样例. 对于每 ...

  8. UUID 生成(源代码编译)

    根据定义,UUID(Universally Unique IDentifier,也称GUID)在时间和空间都是唯一的.为保证空间的唯一性,每个UUID使用了一个48位的值来记录,一般是计算机的网卡地址 ...

  9. BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

    BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...

  10. GUI练习——列出指定目录内容

    需求: 一个窗体里.在文本框输入路径后,摁回车键或者点击"转到"按钮后: 若路径合法,程序会自动在文本域里显示该路径下的文件目录:若路径非法,则弹出对话框,告之你路径非法.点击&q ...