在单链表和双链表中删除倒数第K个节点
【说明】:
本文是左程云老师所著的《程序员面试代码指南》第二章中“在单链表和双链表中删除倒数第K个节点”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
分别实现两个函数,一个可以删除单链表中倒数第 K 个节点,另一个可以删除双链表中倒数第 K 个节点。
【要求】:
如果链表长度为 N,时间复杂度达到 O(N),额外空间复杂度达到 O(1)。
【思路】:
在确定待删除节点的位置有一个小技巧,大家可以看代码推断,也可以翻看左老师的原书奥。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
实现及测试代码:
/*
*文件名:lists_delLastKth.cpp
*作者:
*摘要:删除单链表或双链表的倒数第 K 个节点
*/ #include <iostream> using namespace std; struct SingleNode
{
int value;
SingleNode *next;
}; struct DoubleNode
{
int value;
DoubleNode *pre;
DoubleNode *next;
}; SingleNode* removeLastKthNode(SingleNode *head,int lastKth)
{
if(NULL == head || > lastKth)
return head;
SingleNode *cur = head;
while( NULL != cur)
{
lastKth--;
cur = cur->next;
}
if( == lastKth)
{
cur = head;
head = head->next;
delete cur;
}
if( > lastKth)
{
cur = head;
while(++lastKth != )
cur = cur->next;
SingleNode *tmp = cur->next;
cur->next = tmp->next;
delete tmp;
}
return head;
} DoubleNode* removeLastKthNode(DoubleNode *head,int lastKth)
{
if(NULL == head || > lastKth)
return head;
DoubleNode *cur = head;
while( NULL != cur)
{
lastKth--;
cur = cur->next;
}
if( == lastKth)
{
cur = head;
head = head->next;
head->pre = NULL;
delete cur;
}
if( > lastKth)
{
cur = head;
while(++lastKth != )
cur = cur->next;
DoubleNode *tmp = cur->next;
cur->next = tmp->next;
if(NULL != tmp->next)
tmp->next->pre = cur;
delete tmp;
}
return head;
} int main()
{
SingleNode *shead = NULL;
SingleNode *sptr;
DoubleNode *dhead = NULL;
DoubleNode *dptr;
for(int i =;i<;i++)
{
if(NULL == shead && NULL == dhead)
{
//单链表
shead = new SingleNode;
shead->value = i;
shead->next = NULL;
sptr = shead;
//双链表
dhead = new DoubleNode;
dhead->value = i;
dhead->next = NULL;
dhead->pre = NULL;
dptr = dhead;
continue;
}
//单链表
sptr->next = new SingleNode;
sptr = sptr->next;
sptr->value = i;
sptr->next = NULL;
//双链表
dptr->next = new DoubleNode;
dptr->next->pre = dptr;
dptr = dptr->next;
dptr->value = i;
dptr->next = NULL;
}
int k = ;
cout << "Single linked list before remove last " << k << "th data: " << endl;
sptr = shead;
while(NULL != sptr)
{
cout << sptr->value << " ";
sptr = sptr->next;
}
cout << endl;
cout << "Double linked list before remove last " << k << "th data: " << endl;
dptr = dhead;
while(NULL != dptr)
{
cout << dptr->value << " ";
dptr = dptr->next;
}
cout << endl; removeLastKthNode(shead,k);
removeLastKthNode(dhead,k); sptr = shead;
dptr = dhead;
cout << "Single linked list after removed: " << endl;
while(NULL != sptr)
{
cout << sptr->value << " ";
sptr = sptr->next;
}
cout << endl;
cout << "Double linked list after removed: " << endl;
while(NULL != dptr)
{
cout << dptr->value << " ";
dptr = dptr->next;
}
cout << endl;
return ;
}
【说明】:
这个算法不难,我写的测试代码(main 函数)较为麻烦,大家理解哈。
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。
在单链表和双链表中删除倒数第K个节点的更多相关文章
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点
题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...
- 链表中删除倒数第K个节点
问题描述 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 问题分析与解决 从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如 ...
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
- 在单链表和双链表中删除倒数第k个结点
题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...
- [算法]在单链表和双链表中删除倒数第k个结点
题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...
- 链表问题----删除倒数第K个节点
在单链表和双链表中删除倒数第K个节点 分别实现两个函数,一个可以删除单链表中的倒数第K个节点,一个可以删除双链表中的倒数第k 个节点,要求时间复杂度是 O(N),空间复杂度是 O(1). [解析] 基 ...
- 左神算法书籍《程序员代码面试指南》——2_02在单链表和双链表中删除倒数第k个字节
[题目]分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点.[要求]如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]从头遍历链表, ...
- 链表实现比较高效的删除倒数第k项
最近写链表不太顺,无限的段错误.今天中午写的链表删除倒数第k项,用的带尾节点的双向链表,感觉已经把效率提到最高了,还是超时,改了很多方法都不行,最 终决定看博客,发现原来是审题错了,阳历给的是以-1结 ...
- 1.求链表中的倒数第K个节点
注意事项:1.要是K大于链表长度怎么办? 2.k<=0怎么办? ListNode* FindR_Kth(ListNode* p_head, unsigned int k) 2 {//找到链表的倒 ...
随机推荐
- dom4j和jaxp解析工具的
dom4j解析中的几个对象 node --branch --document --element --commment --attribute --text branch --document --e ...
- pywebkitgtk安装出现的问题
configure 文件里 print sys.prefix 等不能支持python3的原因 依据http://blog.csdn.net/jklfjsdj79hiofo/article/detail ...
- CString 与 std::string 相互转化
MFC中CString 与 std::string 相互转化 CString实际是CStringT, 也就是模板类, 在UNICODE环境下,实际是CStringW, 在多字符集环境下,实际是CStr ...
- SlidingMenu的编译及使用
1. 在github上有一个效果不错的开源库,SlidingMenu 最新的代码下载下来后,ExampleListActivity项目会报错: No resource found that ...
- Excel几个常用操作
1.冻结第一行:视图->冻结窗格->冻结首行 2.第一行自动筛选:选择要设置的行,数据->筛选->自动筛选 3.在单元格中添加下拉菜单:(1)选中一列,数据->数据验证. ...
- Openv2.1基本数据类型
1.Point_ template<typename _Tp> class Point_ {_Tp x, y;} 可使用的运算: pt1 = pt2 + pt3; pt1 = pt2 - ...
- C++数据类型简析
C++语言的基本数据类型有如下四种: 整型,说明符为int: 字符型,说明符为char: 浮点型(又称实型),说明符为float(单精度),double(双精度): 空值型,说明符为void,用于函数 ...
- errorPlacement的位置问题
做一个前端的验证,使用了JQUERY.Validate 在errorPlacement上纠结了半天: 百度大多数都是一个答案: errorPlacement: function(error, elem ...
- 使用#define定义字面值和伪函数
#define是C语言提供的宏命令,其主要目的是:在编程时,为程序员提供一定方便,并能在一定程度上提高程序的执行效率.#define将一个标示符定义为一个字符串,该标示符被称为宏,被定义的字符串称为字 ...
- Netty4.0学习教程
http://blog.csdn.net/u013252773/article/details/21046697 一些属性和方法介绍 http://blog.csdn.net/zxhoo/articl ...