将单链表的每K个节点之间逆序
【说明】:
本文是左程云老师所著的《程序员面试代码指南》第二章中“将单链表的每K个节点之间逆序”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
给定一个单链表的头节点 head,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。
例如:
链表:1->2->3->4->5->6->7->8->NULL,K = 3.
调整后为:3->2->1->6->5->4->7->8->NULL。其中7、8不调整,因为不够一组。
【思路】:
解法一:使用栈,每K个清空栈来进行逆序。
解法二:需要保存即将逆序的K个节点的前一个节点pre和后一个节点next
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
实现及测试代码:
/*
*文件名:list_reverse.cpp
*作者:
*摘要:将单链表的每K个节点之间逆序
*/ #include <iostream>
#include <stack> using namespace std; class Node
{
public:
Node(int data)
{
value = data;
next = NULL;
}
public:
int value;
Node *next;
}; Node* resign1(stack<Node*> &s,Node *left,Node *right)
{
Node *cur = s.top();
s.pop();
if(NULL != left)
left->next = cur;
Node *next = NULL;
while(!s.empty())
{
next = s.top();
s.pop();
cur->next = next; //反转
cur = next;
}
cur->next = right;
return cur;
} Node* reverseKNodes1(Node *head,int K)
{
if(K < )
return head;
stack<Node*> s;
Node *newHead(head),*cur(head),*pre(NULL),*next(NULL);
while(NULL != cur)
{
next = cur->next;
s.push(cur);
if(s.size() == K)
{
pre = resign1(s,pre,next);
newHead = newHead == head ? cur : newHead;
}
cur = next;
}
return newHead;
} void resign2(Node *left,Node *start,Node *end,Node* right)
{
Node *pre = start;
Node *cur = start->next;
Node *next = NULL;
while(cur != right)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
if(NULL != left)
left->next = end;
start->next = right;
} Node* reverseKNodes2(Node *head,int K)
{
if( > K)
return head;
Node *cur(head),*start(NULL),*pre(NULL),*next(NULL);
int count = ;
while(NULL != cur)
{
next = cur->next;
if(count == K)
{
start = pre == NULL ? head : pre->next;
head = pre == NULL ? cur : head; //第一次发生变化的时候确定head
resign2(pre,start,cur,next);
pre = start;
count = ;
}
count++;
cur = next;
}
return head;
} void printList(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(i);
ptr = head;
continue;
}
ptr->next = new Node(i);
ptr = ptr->next;
}
cout << "Before reverse:" << endl;
printList(head);
cout << "First reverse:" << endl;
head = reverseKNodes1(head,);
printList(head);
cout << "Second reverse:" << endl;
head = reverseKNodes2(head,);
printList(head);
return ;
}
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。
将单链表的每K个节点之间逆序的更多相关文章
- 【链表问题】打卡9:将单链表的每K个节点之间逆序
前言 以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获.每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢. 注:如果代码排版出现了问题麻烦通知我下 ...
- 栈和队列----将单链表的每K个节点之间逆序
将单链表的每K个节点之间逆序 给定一个单链表的头节点head,实现一个调整链表的函数,使得每K 个节点之间逆序,如果最后剩下不够K 个节点,则不调整最后几个. 例如: 链表:1—>2—>3 ...
- [算法] 将单链表的每K个节点之间逆序
题目 给定一个单链表的头结点,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点. 解答 使用栈结构 import java.util.Stack; pu ...
- 算法总结之 将单链表的每K个节点之间逆序
给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点 思路: 如果k的值小于2,不调整.k<1 没有意义,k==1代 ...
- 左神算法书籍《程序员代码面试指南》——2_11将单链表的每K个节点之间逆序
[题目]给定一个单链表的头节点head,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点.例如:链表:1->2->3->4->5 ...
- [程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序
题目描述 给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点. 题解 内部函数reverse实现链表beg到end的翻转 ...
- 《程序员代码面试指南》第二章 链表问题 将单链表每K个节点之间逆序
样例 链表1-2-3-4-5-6-7-8-9-10 K=3 ,结果 3-2-1-6-5-4-9-8-7-10 java代码 /** * @Description:将单链表每K个节点之间逆序 * @Au ...
- [剑指offer] 14. 链表中倒数第K个节点+翻转+逆序打印+合并两个排序链表 + 链表相交(第一个公共节点) (链表)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 两个指针,起始位置都是从链表头开始,第一个比第二个先走K个节点,当第一个走到链表尾时,第二个指针的位置就是倒数第k个节点.(两指针始终相 ...
- 【链表问题】打卡2:删除单链表的第 K个节点
前言 以专题的形式更新刷题贴,欢迎跟我一起学习刷题.每道题会提供简单的解答. 题目描述 在单链表中删除倒数第 K 个节点 要求 如果链表的长度为 N, 时间复杂度达到 O(N), 额外空间复杂度达到 ...
随机推荐
- 在自定义的js验证规则中调用magento的VarienForm方法验证表单
js部分<script type="text/javascript"> //<![CDATA[ var loginForm = new VarienForm('l ...
- 《github一天一道算法题》:插入排序
看书.思考.写代码! /*********************************************** * copyright@hustyangju * blog: http://bl ...
- Data Structure(3)——软考阶段学习小结
数据结构计算机等级考试中有,自考中有,软考中同样有,可见其内容的重要程度,今天对软考阶段视频学习内容的总结,同样是对前面学习内容的回顾,同样是对后面学习的铺垫. 中结:原本因为之前有过类似的总结,这次 ...
- 在SQL Server 2008 中使用SQL脚本创建登录用户并授权
到处都使用超级用户sa显然是不安全的,因此有创建用户并让其只能访问某个数据库的必要.当然可以使用SQL Server自带的图形界面向导,但是太难用用了!有时候代码比较直接,比如这里: --使用已经创建 ...
- win32 控件的创建和消息响应
1. 控件的创建 控件的创建和窗口创建是一样的,例如: ,,,, hWnd,(HMENU)IDB_BUTTON01,hInst,NULL); 是一个按钮的创建,其中hWnd是窗口句柄,hInst是应用 ...
- 相见恨晚——MarkDown
什么是MarkDown MarkDown是一种轻量级的标记语言 MarkDown使你更加关注文章的内容 MarkDown使文章的排版变得简单直接 什么情景下使用MarkDown 在我们熟悉的githu ...
- 利用汇编查看C++函数调用
这篇文章的内容是一个老生常谈的问题----> 函数是如何被调用的. 本文用汇编代码研究函数调用的过程,参数调用的方式,函数值的返回. 1. 函数是如何实现调用的 函数的调用是用call 和 re ...
- 解决Ubuntu DNS解析慢、上网速度慢
自从ubuntu升级到10.04后,上网速度感觉变慢了很多(ADSL),原因也众说分云,有说是firefox浏览器造成的,于是用chrome访问,速度依然很慢,可见不是由于浏览器造成的. 网速慢, 是 ...
- Android Studio git ignore
# Built application files *.apk *.ap_ # Files for the Dalvik VM *.dex # Java class files *.class # G ...
- Android GreenDao with Android Studio IDE
转:http://blog.surecase.eu/using-greendao-with-android-studio-ide/ In this tutorial we will show you ...