C++ 链表部分逆序

已知链表头节点指针head,将链表从位置m到n逆序。(不申请额外空间)

#include<stdio.h>
struct ListNode
{
 int val;       //数据域
 ListNode* next;   //指针域
 ListNode(int x): val(x),next(NULL) {}      //构造函数
};
class Solution
{
public:
 Solution(){}
 ~Solution(){}
 ListNode* reverseBetween(ListNode* head, int m, int n)
 {
  int change_len = n - m + 1;        
  ListNode* pre_head = NULL;
  ListNode* result = head;
  while (head && --m)         
  //如果为while (head && --m),m先自减再判断,判断时经过自减后是从m-1到1,m本身是从m到2,共m-1次循环
  //如果为while (head && m--),m先判断再自减,判断时未自减是从m到1,m本身是从m到1,共m次循环
  {
   pre_head = head;         
   head = head->next;        
  }                 //循环结束时head到达第m个节点, pre_head到达第m-1个节点
  ListNode* modify_list_tail = head;              //此时为第m个节点
  ListNode* new_head = NULL;      //原逆序部分的尾部
  while (head && change_len--)     //共逆序change_len次
  {
   //第一个循环开始时head在第m个节点, next在第m+1个节点,结束时head在第m+1个节点。
   //第二个开始循环时,head在第m+1个节点,next在第m+2个节点,结束时head在第m+2个节点。
   //第change_len个循环开始时,head在第m+change_len-1=m+n-m+1-1=n个节点,结束时head在第n+1个节点。
   ListNode* next = head->next;       //备份。
   head->next = new_head;      //将原顺序序列的第一个元素的指针指向新逆序序列
   new_head = head;         //将新逆序序列的头指向新加的节点
   head = next;           //将原顺序序列的指针移至后一个节点
   //change_len--;
  }                 //循环结束时head到达n+1,new_head到达n,
  modify_list_tail->next = head;     //将逆序尾链接到n+1
  if (pre_head)
  {
   pre_head->next = new_head;                //将n-1个节点中的指针指向第n个节点。
  }
  else
  {
   result = new_head;
  }
  return result;
 }
};
int main()
{
 ListNode a(1);
 ListNode b(2);
 ListNode c(3);
 ListNode d(4);
 ListNode e(5);
 ListNode f(6);
 ListNode g(7);
 ListNode h(8);
 a.next = &b;
 b.next = &c;
 c.next = &d;
 d.next = &e;
 e.next = &f;
 f.next = &g;
 g.next = &h;
 Solution solve;
 ListNode* head = solve.reverseBetween(&a, 4, 7);
 while (head)
 {
  printf("%d\n", head->val);
  head = head->next;
 }
 return 0;
}

运行结果:
1
2
3
7
6
5
4
8

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值