删除链表的中间节点和a/b处节点
【说明】:
本文是左程云老师所著的《程序员面试代码指南》第二章中“删除链表的中间节点和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处节点的更多相关文章
- 《程序员代码面试指南》第二章 链表问题 删除中间节点和a/b处节点
题目 例如 1-2-3-4 删除2,1-2-3-4-5 删除3 例如 a=1,b =2 java代码 /** * @Description:删除中间节点和a/b处节点 * @Author: lizho ...
- 数据结构:DHUOJ 删除链表的顺数及倒数第N个节点
删除链表的顺数及倒数第N个节点 作者: turbo时间限制: 1S章节: DS:数组和链表 题目描述: 可使用以下代码,完成其中的removeNth函数,其中形参head指向无头结点单链表,n为要删除 ...
- 删除链表中等于给定值val的所有节点。
样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5. /** * D ...
- 【leetcode 简单】 第五十七题 删除链表中的节点
删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4 ...
- LeetCode:删除链表中的节点【203】
LeetCode:删除链表中的节点[203] 题目描述 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val ...
- lintcode:删除链表中指定元素
题目 删除链表中等于给定值val的所有节点. 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1-> ...
- 动图:删除链表的倒数第 N 个结点
本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点.采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组. 19. 删除链表的倒 ...
- [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 ...
- [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 ...
随机推荐
- 轻轻谈一下seaJs——模块化开发的利器
"仅做一件事,做好一件事." 这个应该就是seaJs的精髓了. 我在自己的一些项目中使用过seaJs.对其算是了解一二.如今就班门弄斧.轻轻地谈一下. 首先上一段度娘的话: &qu ...
- Android版xx助手之天天酷跑外挂具体分析
Android版xx助手之天天酷跑外挂具体分析 图/文 莫灰灰 背景 近些年来,移动互联网的大肆崛起,潜移默化中影响着人们的生活和工作习惯.当腾讯的微信平台接入手机游戏之后,移动端的游戏也開 ...
- LeetCode总结 -- 高精度篇
我们常见的一些主要的数据结构比方整型int或者浮点型float由于位数过多无法用内置类型存储,这时候我们就须要自己实现高精度的数据类型来进行存储和运算.这样的问题在实际产品中还是比較有用的,所以相对来 ...
- 最新版SDWebImage的使用
我之前写过一篇博客,介绍缓存处理的三种方式,其中最难,最麻烦,最占内存资源的还是图片缓存,最近做的项目有大量的图片处理,还是采用了SDWebImage来处理,但是发现之前封装好的代码报错了.研究发现, ...
- linq中的cast<T>()及OfType<T>()
DataTable dt=...........//获取从数据库中取出的数据(假设只有一条记录) //Cast<T>()用来将非泛型的序列转换为泛型的序列 DataRow row=dt.R ...
- Csharp多态的实现(虚方法)
1.什么是抽象类 1.1虚方法是用virtual修饰,在子类中用override进行重写 1.2虚方法是一个方法,放在类里面(可以再下面的代码中看到) 1.3虚方法可以 重写,也可以不重写(这个可以再 ...
- [Jobdu] 题目1506:求1+2+3+...+n
题目描述: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 输入: 输入可能包含多个测试样例. 对于每 ...
- UUID 生成(源代码编译)
根据定义,UUID(Universally Unique IDentifier,也称GUID)在时间和空间都是唯一的.为保证空间的唯一性,每个UUID使用了一个48位的值来记录,一般是计算机的网卡地址 ...
- BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )
BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...
- GUI练习——列出指定目录内容
需求: 一个窗体里.在文本框输入路径后,摁回车键或者点击"转到"按钮后: 若路径合法,程序会自动在文本域里显示该路径下的文件目录:若路径非法,则弹出对话框,告之你路径非法.点击&q ...