反转部分单向链表

【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第二章中“反转部分单向链表”这一题目的C++复现。

  本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。

  感谢左程云老师的支持。

【题目】:

  给定一个单向链表的头节点 head,以及两个整数 from 和 to,在单向链表上把第 from 个节点到第 to 个节点这一部分进行反转。

  例如:

  1->2->3->4->5->NULL,from=2,to=4

  调整结果为:1->4->3->2->5->NULL

  再如:

  1->2->3->NULL,from=1,to=3

  调整结果为:3->2->1->NULL

【要求】:

  1、如果链表长度为 N,时间复杂度的要求为 O(N),额外的空间复杂度要求为O(1)。

  2、如果不满足1<=from<=to<=N,则不用调整。

 【思路】:

  整体的思路与链表的反转是差不多的,但是判断 from 的前一个节点和 to 的后一个节点的位置是有技巧的。

【编译环境】:

  CentOS6.7(x86_64)

  gcc 4.4.7

 【实现】:

  实现及测试代码:

 1 /*
 2  *文件名:lists_reversePart.cpp
 3  *作者:
 4  *摘要:单链表部分反转的C++实现
 5  */
 6 
 7 #include <iostream>
 8 
 9 using namespace std;
10 
11 struct Node
12 {
13     int value;
14     Node *next;
15 };
16 
17 Node* reversePart(Node *head,int from,int to)
18 {
19     if(NULL == head || from > to || from < 1)
20         return head;
21     int len = 0;
22     Node *node1 = head;
23     Node *fPre = NULL;      //from位置的前一个节点
24     Node *tPos = NULL;      //to位置的后一个节点
25     while(NULL != node1)  //计算链表的长度,并确定fPre 和 tPos
26     {
27         len++;
28         fPre = (len == from-1 ? node1 : fPre);
29         tPos = (len == to+1 ? node1 : tPos);
30         node1 = node1->next;
31     }
32     if(to > len)
33         return head;
34 
35     node1 = (fPre == NULL ? head : fPre->next);  //from位置的节点
36     Node *node2 = node1->next;
37     node1->next = tPos;        //from->next指向to之后的第一个节点tPos
38     Node *next = NULL;
39     //反转from至to之间的节点
40     while(node2 != tPos)    //node2为当前;node1为之前;next为之后
41     {
42         next = node2->next;
43         node2->next = node1;
44         node1 = node2;
45         node2 = next;
46     }
47     if(NULL != fPre)    //from节点非head节点时
48     {
49         fPre->next = node1;
50         return head;
51     }
52     return node1;
53 }
54 
55 void printLists(Node *head)
56 {
57     while(NULL != head)
58     {
59         cout << head->value << " " ;
60         head = head->next;
61     }
62     cout << endl;
63 }
64 
65 int main()
66 {
67     Node *head = NULL;
68     Node *ptr = NULL;
69     
70     for(int i =0;i<10;i++)//构造链表
71     {
72         if(NULL == head)
73         {    
74             head = new Node;
75             head->value = i;
76             head->next = NULL;
77             ptr = head;
78             continue;
79         }
80         ptr->next = new Node;
81         ptr = ptr->next;
82         ptr->value = i;
83         ptr->next = NULL;
84     }
85 
86     cout << "Before part reversed: " << endl;
87     printLists(head);
88     head = reversePart(head,3,8);
89     cout << "After remove mid: " << endl;
90     printLists(head);
91     return 0;
92 }
View Code

 

注:

  转载请注明出处;

  转载请注明源思路来自于左程云老师的《程序员代码面试指南》。

转载于:https://www.cnblogs.com/PrimeLife/p/5362522.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值