【说明】:

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

    如果你的IPTABLES基础知识还不了解,建议先去看看. 们来配置一个filter表的防火墙 1.查看本机关于IPTABLES的设置情况 [root@tp ~]# iptables -L -n Cha ...

  2. 桂林电子科技大学出校流量控制器Android版1.0.0

    每次玩游戏的时候,总是要开着电脑挂着出校控制器,真是浪费国家资源啊,,, 突然想起学校有个开放流量的网页,无奈UC等浏览器真是尝试优化js脚本啊,挂在后台,不到几分钟就掉线了,悲剧啊~~~ 还好And ...

  3. 在iOS当中发送电子邮件和短信

    iOS实现发送电子邮件的方法很简单,首先导入MessageUI.framework框架,然后代码如下: #import "RPViewController.h" //添加邮件头文件 ...

  4. error while loading shared libraries: libevent-1.x.so.1

    安装完memcache后启动报错(error while loading shared libraries: libevent-1.x.so.1) 这是由于64位linux会去/usr/lib64目录 ...

  5. cocos2d-x 3.0rc2 对于每个包执行情况的重要平台 (超级方便)

    首先,你需要下载三个文件:每间 android-ndk android-sdk ant 下载位置可以随意:由于3.0rc2执行setup.py  自己主动搜索这三个文件 win32cmd以下: (1) ...

  6. 队列的实现 -- 数据结构与算法的javascript描述 第五章

    队列也是列表的一种,有不同于列表的规则. 先进先出 入队方法 出队方法 可以找到队首 可以找到队尾 可以查看队列有多长 可以查看队列是否为空 这是一个基本的需求,围绕他来实现,当然我们可以自己扩展列表 ...

  7. web - 块元素和内嵌元素的特征

    块: 1.独占一行 2.支持所有的样式 3.不设置宽度的时候,宽度撑满整行 常用的快标签有: div,section,header,nav,footer,article,aside,ul,ol,li, ...

  8. 使用 NuGet 管理项目库

    使用 NuGet 管理项目库 Phil Haack 本文转载自:http://msdn.microsoft.com/zh-cn/magazine/hh547106.aspx 无论多么努力,Micros ...

  9. 在centos6.5下yum仓库的创建

    第一步:打开虚拟机,装入光盘镜像,选择为已连接 第二步: df -h mount umount /dev/sr0 mkdir /centos mount /dev/sr0 /centos mkdir ...

  10. jQuery实时获取checkbox状态问题

    在最近的项目开发中,使用jQuery操作checkbox时,发现一个问题. Html代码如下: <body> <div> <inputtype="checkbo ...