链表翻转
来源:互联网 发布:spss软件 教学大纲 编辑:程序博客网 时间:2024/06/05 14:21
问题
链表翻转。给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5,用程序实现。
在之前我们肯定都写过链表的翻转程序:
NodePtr ReverseList(NodePtr head){cout << "reverse list" << endl;//若只有头或者只有一个节点,则不用翻转if(head->next == NULL || head->next->next == NULL) return head;NodePtr p, q, r;p = head->next;q = p->next;//翻转过程while(q){ r = q->next; q->next = p; p = q; q = r;} //翻转过后改变头指针head->next = p;return head;}
本题与全翻转链表有很大的相似之处,当然也有很大的不同之处。相似之处在于翻转的过程同事相同的,而不同之处则在于本题中包含两个部分的翻转,并且在头指针的指向以及第一个翻转过后还有一些操作需要处理。大致过程如下草图所示
该图中黑色表示链表的最初始状态,红色表示翻转的第一部分,绿色表示第二部分的翻转。
该实例表示的是k=2时的翻转,第一部分的翻转我们需要注意的问题是:
1.准确的定位。在链表中有时候会把人弄糊涂,因此一定要准确的定位到第二个节点,然后再开始翻转。
2.翻转过后头结点的指向。在本例中第一部分翻转过后一定要将head节点指向第一部分翻转的起始节点,即第二个节点。
3.第一部分翻转过后的最后一个节点的指向也一定要搞清楚。在本例中翻转过后第一个节点的下一个指向一定要指向节点3.
第一部分翻转完成过后我们开始第二部分的翻转。第二部分的翻转相对而言要简单很多,只需要注意翻转过后,一定要将第一部分翻转过后的最后一个节点的next指向最后一个节点。程序代码如下所示(这个程序还是有一点问题的,如果是全翻转的话会有问题,但是这只是增加判断的问题,主要思路都是对的)
bool ReverseLink(LinkList link, int k){//若只有头或者只有一个节点,则不用翻转if(link->next == NULL || link->next->next == NULL) return false;LinkList p, q, r, firstNode;int count = 1;firstNode = link->next;p = link->next; //头结点 q = p->next; //第二个节点//前k个节点的翻转 while(count<k && q){ r = q->next; q->next= p; p = q; q = r; count++;} firstNode->next = r;link->next = p;//后面节点的翻转p = firstNode->next;q = p->next; while(q){ r = q->next; q->next = p; p = q; q = r;}firstNode->next->next = NULL;firstNode->next = p;return true; }
下面是整体的代码,可以直接运行,已经在机器上测试过:
#include<iostream>using namespace std;typedef int ElemType;struct Link{ ElemType data; struct Link *next;};typedef Link *LinkList;bool InitLink(LinkList *link){ *link = (LinkList)malloc(sizeof(Link)); if(!(*link)) return false; (*link)->next = NULL; return true;}bool InsertList(LinkList *link, ElemType elem){ if(NULL == *link) return false; LinkList p, q; p = *link; q = (LinkList)malloc(sizeof(Link)); q->data = elem; q->next = NULL; while(NULL != p->next) p = p->next; p->next = q; return true;}bool ReverseLink(LinkList link, int k){ //若只有头或者只有一个节点,则不用翻转 if(link->next == NULL || link->next->next == NULL) return false; LinkList p, q, r, firstNode; int count = 1; firstNode = link->next; p = link->next; //头结点 q = p->next; //第二个节点 //前k个节点的翻转 while(count<k && q){ r = q->next; q->next= p; p = q; q = r; count++; } firstNode->next = r; link->next = p; //后面节点的翻转 p = firstNode->next; q = p->next; while(q){ r = q->next; q->next = p; p = q; q = r; } firstNode->next->next = NULL; firstNode->next = p; return true; }void printLink(LinkList link){ LinkList p; p = link; while(NULL != p->next ){ cout << p->next->data << "---> " ; p = p->next; } cout << endl;}int main(){ LinkList link; InitLink(&link); InsertList(&link, 1); InsertList(&link, 2); InsertList(&link, 3); InsertList(&link, 4); InsertList(&link, 5); InsertList(&link, 6); printLink(link); ReverseLink(link, 5); printLink(link); return 0;}
0 0
- 无情链表的创建,,翻转翻转
- 链表翻转程序
- 链表翻转
- 链表翻转
- 链表翻转
- 翻转单向链表
- 翻转链表
- 原地翻转链表
- 链表的翻转
- 链表翻转
- 翻转部分链表
- 链表翻转
- 链表翻转
- c++翻转链表
- 翻转链表
- 链表翻转
- 翻转链表
- 链表翻转
- 类的相关图解
- Python Pysde 离线文档
- autorelease
- Linux内核如何装载和启动一个可执行程序
- Linux学习笔记(系统日常管理-3)
- 链表翻转
- 黑马程序员——集合类
- CentOS 64位 搭建LAMP环境
- java 对象数组小结
- 关于xilinx14.7 在modelsim SE 10.1a仿真中遇到的若干问题
- 3-12
- Dedecms生成sitemap.xml的简单方法
- String类和StringBuffer类
- boost资料