【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第二章中“删除链表的中间节点和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

【实现】:

  实现及测试代码:

 /*
*文件名:lists_remove.cpp
*作者:
*摘要:实现删除链表的中间节点和 a/b 处的节点
*/
#include <iostream>
#include <math.h> using namespace std; struct Node
{
int value;
Node *next;
}; //删除中间节点
Node* removeMidNode(Node *head)
{
if(NULL == head || NULL == head->next)
return head; if(NULL == head->next->next)
{
Node *ptr = head;
head = head->next;
delete ptr;
} Node *pre = head;
Node *cur = head->next->next;
//找到待删除的中间节点的前一个(非双向链表)节点
while(NULL != cur->next && NULL != cur->next->next)
{
pre = pre->next;
cur = cur->next->next;
}
//将cur用作辅助指针
cur = pre->next;
pre->next = pre->next->next;
delete cur;
return head;
} //进阶问题,删除 a/b 节点
Node* removeByRatio(Node *head,int a,int b)
{
if(a < || a > b)
return head;
int n = ;
Node *cur = head; while(NULL != cur) //统计链表中节点个数->n
{
n++;
cur = cur->next;
}
//由小数区间转化为整数,这是本题最有技巧的地方
n = (int)ceil( ((double) (a*n)) / ((double) b) ); if( == n)
{
cur = head;
head = head->next;
delete cur;
} if( < n)
{
cur = head;
while( --n != ) //找到待删除节点的前一个节点
cur = cur->next;
Node *ptr = cur->next;
cur->next = cur->next->next;
delete ptr;
}
return head;
} //打印链表内容
void printLists(Node *head)
{
while(NULL != head)
{
cout << head->value << " " ;
head = head->next;
}
cout << endl;
} int main()
{
Node *head = NULL;
Node *ptr = NULL; for(int i =;i<;i++)//构造链表
{
if(NULL == head)
{
head = new Node;
head->value = i;
head->next = NULL;
ptr = head;
continue;
}
ptr->next = new Node;
ptr = ptr->next;
ptr->value = i;
ptr->next = NULL;
} cout << "Before remove mid: " << endl;
printLists(head);
head = removeMidNode(head);
cout << "After remove mid: " << endl;
printLists(head); int a(),b();
cout << "Before remove "<< a << "/" << b << ": "<< endl;
printLists(head);
head = removeByRatio(head,a,b);
cout << "After remove "<< a << "/" << b << ": "<< endl;
printLists(head); return ;
}

注:

  转载请注明出处;

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

删除链表的中间节点和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. [原]性能优化之Hibernate缓存讲解、应用和调优

    近来坤哥推荐我我们一款性能监控.调优工具--JavaMelody,通过它让我觉得项目优化是看得见摸得着的,优化有了针对性.而无论是对于分布式,还是非分布,缓存是提示性能的有效工具. 数据层是EJB3. ...

  2. Django里面的自定义tag和filter

    Django的文档里面有这么一句 The app that contains the custom tags must be in INSTALLED_APPS  in order for the { ...

  3. 杭电 1272 POJ 1308 小希的迷宫

    这道题是我学了并查集过后做的第三个题,教我们的学姐说这是并查集的基础题,所以有必要牢牢掌握. 下面就我做这道题的经验,给大家一些建议吧!当然,我的建议不是最好的,还请各位大神指出我的错误来,我也好改正 ...

  4. HTML系列(九):表单

    一.表单标签form 表单标签用于申明表单,定义采集数据的范围,即<form>包含的数据将被提交到数据库上,包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单能够包 ...

  5. SQL学习之联结表的使用

    1.简介:"联结(join)表"是SQL最强大的功能之一.联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分! 在能够有效的使用 ...

  6. text选中后displa出label内容

    效果很好而且很简单 用text的click属性即可 private sub text1_click()label1.caption="******"label2.caption=& ...

  7. 2014-11-21 DHTMLX是什么

    什么是dhtmlx? dhtmlx是一套网页开发 的函式库,他提供了树状元件.数据方格组件.工具列等组件供开发 人员使用. dhtmlx组件是一个JavaScript 库,提供了一套完整的Ajax驱动 ...

  8. English - 定冠词和不定冠词(a an the) 的区别

    不定冠词表示泛指,定冠词表示特指. 不定冠词a (an)与数词one 同源,是"一个"的意思.a用于辅音音素前,一般读作[e],而an则用于元音音素前,一般读做[en]. 1) 表 ...

  9. osg项目经验1<MFC+OSG中模型点选效果>

    点选主要是重载osg的GUIEventHandler, class CPickHandler : public osgGA::GUIEventHandler{ //自定义回调函数名:CPickHand ...

  10. MVC上传文件受限制

    mvc自带设置4M一下的字体可以上传,4M以上的字体需要对web.config进行设置 <system.web> <httpRuntime targetFramework=" ...