【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第二章中“在单链表和双链表中删除倒数第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个节点的更多相关文章

  1. 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点

    题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...

  2. 链表中删除倒数第K个节点

    问题描述 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 问题分析与解决 从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如 ...

  3. 算法总结之 在单链表和双链表中删除倒数第k个节点

    分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...

  4. 在单链表和双链表中删除倒数第k个结点

    题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...

  5. [算法]在单链表和双链表中删除倒数第k个结点

    题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...

  6. 链表问题----删除倒数第K个节点

    在单链表和双链表中删除倒数第K个节点 分别实现两个函数,一个可以删除单链表中的倒数第K个节点,一个可以删除双链表中的倒数第k 个节点,要求时间复杂度是 O(N),空间复杂度是 O(1). [解析] 基 ...

  7. 左神算法书籍《程序员代码面试指南》——2_02在单链表和双链表中删除倒数第k个字节

    [题目]分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点.[要求]如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]从头遍历链表, ...

  8. 链表实现比较高效的删除倒数第k项

    最近写链表不太顺,无限的段错误.今天中午写的链表删除倒数第k项,用的带尾节点的双向链表,感觉已经把效率提到最高了,还是超时,改了很多方法都不行,最 终决定看博客,发现原来是审题错了,阳历给的是以-1结 ...

  9. 1.求链表中的倒数第K个节点

    注意事项:1.要是K大于链表长度怎么办? 2.k<=0怎么办? ListNode* FindR_Kth(ListNode* p_head, unsigned int k) 2 {//找到链表的倒 ...

随机推荐

  1. poj2196---Specialized Four-Digit Numbers

    #include <stdio.h> #include <stdlib.h> int main() { int i,sum,sumOfH,sumOfd,tmp1,tmp2,tm ...

  2. var 与function的权重浅析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

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

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

  4. 随心所欲~我也做个集合遍历器吧(自己的foreach,委托的威力)

    感觉微软在面向对象三大原则中,封装性运用的最为突出,它会将一些复杂的算法,结构,功能代码进行封装,让程序员在使用时十分得心应手,如关键字里的foreach和labmda表达式里的Foreach等等,今 ...

  5. java读取TXT文件的方法

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  6. Web页面引入文档编辑器报风险

    Web页面引入文档编辑器会报风险,则需要以下操作: <system.web> <httpRuntime requestValidationMode="2.0" / ...

  7. jQuery Mobile基础

    1.安装 在<head></head>标签里边写入以下内容 jQuery Mobile CDN: <head> <meta charset="utf ...

  8. jjjjQuery选择器

    此文为作者自用复习文章 jQuery选择器: 它不仅继承了CSS选择器简洁的语法, 还继承了其获取页面便捷高效的特点, 它还拥有更加完善的处理机制: 但jQuery选择器获取元素后,为该元素添加的是行 ...

  9. c++ primer plus 习题答案(1)

    c++ primer plus 习题答案用的是第五版,IDE仍然是vs2013.我只标注了题号,具体的题目找下书上对应内容吧. p110.8 #include<iostream> #inc ...

  10. Excel VLOOKUP等使用记录

    1.LEFT 函数:LEFT(G2,ROW(INDIRECT("76:"&LEN(G2)))) 截取G2单元格从开头,SIZE=76的部分字符串 2.RIGHT 函数:RI ...