删除链表的中间节点和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 ...
随机推荐
- E=MC2 - 搜搜百科
E=MC2 - 搜搜百科 1 E=MC2 质能等价理论是爱因斯坦狭义相对论的最重要的推论,即著名的方程式E=mC^2,式中E为能量,m为质量,C为光速:也就是说,一切物质都潜藏着质量乘于光速平方的能量 ...
- spring bean之间的关系:继承;依赖
概要: ' 继承Bean配置 Spring同意继承bean的配置,被继承的bean称为父bean,继承这个父Bean的Bean称为子Bean 子Bean从父Bean中继承配置,包含Bean的属性配置 ...
- 假设写一个android桌面滑动切换屏幕的控件(一)
首先这个控件应该是继承ViewGroup: 初始化: public class MyGroup extends ViewGroup{ private Scroller mScroller; priva ...
- new、delete与malloc、free的详解
内容清单: 1. C语言中的函数malloc和free 2. C++中的运算符new和delete 3. new/delete与malloc/free之间的联系和区别 4. C/C++程序的内 ...
- sql server group by having 之复习篇
where 与 having 之间的差别在于where 是分组前的过滤,而having是分组后的过滤 Group By中Select指定的字段限制 示例3 select 类别, sum(数量) as ...
- Ueditor和CKeditor 两款编辑器的使用与配置
一丶ueditor 百度编辑器 1.官方文档,演示,下载地址:http://ueditor.baidu.com/website/index.html 2.百度编辑器的好:Editor是由百度web前端 ...
- Win7下安装Mysql方法
最近刚刚在win7系统安装了mysql客户端数据库,现整理步骤供大家学习交流! 一.下载mysql安装包 安装包名称:mysql-5.6.12-win32.zip 下载地址:http://dev.my ...
- sizeof()的用法
机器平台:X86_64 处理器 操作系统:Red Hat 4.1.2-14 编译器: gcc version 4.1.2 20070626 Size of char is: ...
- STL模板_map
map -key - value -键值无法重复 multimap -键值可以重复 声明: -map<int, string> m -multimap<int, string> ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...