链表从m到n逆序

本文介绍了一种C++实现链表中从位置m到n的逆序方法。通过定义ListNode结构体,创建Solution2类,并在类中实现reverseBetween函数,将指定范围内的链表元素进行逆序。在main函数中,创建了一个链表并调用该函数进行逆序操作,最后打印逆序后的链表节点值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>

struct ListNode{
   int val;
   ListNode *next;
   ListNode(int x):val(x),next(NULL){}
   //结构体定义了成员变量列表初始化的时候要用初始化列表初始化
   //初始化列表有空括号,没有分号
};

class Solution2{
  
  public:
  ListNode* reverseBetween(ListNode*head, int m, int n)
    {
      int len=n-m+1; //在原始数据未操作前进行计算修改长度
      ListNode * result = head;
      //找到m的前一个节点,循环结束的时候,l已经到达需要逆序的地一个位置
      //pre_head 用来标记逆序的前一个节点
      ListNode* pre_head=NULL;
     // std::cout<<"m: "<<m<<std::endl;
      while(head && --m)
      {  
        // std::cout<<"m: "<<m<<std::endl;
         pre_head=head;
         head=head->next;
      }
     // std::cout<<"pre_head: "<<pre_head->val<<std::endl;
      //标记逆链表的头节点
      ListNode* rever_tail = head;
     // std::cout<<"rever_tail: "<<rever_tail->val<<std::endl;
      
   //逆序截至的位置是 n-m+1;
   
   // std::cout<<"n:"<<n<<" m: "<<m<<" len: "<<len<<std::endl;
   ListNode* prev=NULL;
   while(head && len)
      {
         ListNode* N= head->next;
         head->next=prev;
         prev=head;
         head=N;
         len--;
      }
          
    //完成逆序之后首尾的连接问题。
    rever_tail->next=head;
    std::cout<<"len: "<<len<<std::endl;
    if(pre_head) //检查逆序链表开始的位置,返回整个数组的头节点
       {
         pre_head->next=prev;
       }else{
              result=prev;
            }   
    return result; 
    }
    
};
int main()
{
  ListNode a(1);
  ListNode b(2);
  ListNode c(3);
  ListNode d(4);
  ListNode e(5);
  a.next=&b;
  b.next=&c;
  c.next=&d;
  d.next=&e;
  e.next=NULL;
  //指针指向了结构体 
  //指针运算符和指向对象的指针一起使用
  Solution2 solve;  
  //类要定义对象,才可以利用成员运算符使用成员函数
  //形参是指针的时候,实参是地址
ListNode* head= solve.reverseBetween(&a,2,4);
  while(head)
    {
       std::cout<<head->val<<std::endl;
       head=head->next;
    }



  return 0;
}

<think>我们被要求使用C++实现链表逆序(反转链表)的算法,并尽可能参考之前提供的引用内容。引用[1]和引用[2]都提供了迭代方法的示例,引用[3]给出了链表节点的定义。此外,我们之前回答中也提供了迭代和递归两种方法。根据要求,我们需要用中文回答,并按照系统级指令处理数学公式(虽然本题可能较少涉及数学公式,但如果有则需用$...$或$$...$$)。同时,我们需要在回答末尾生成相关问题,并在引用处添加引用标识。这里我们主要介绍两种方法:迭代法和递归法。迭代法空间复杂度为O(1),递归法空间复杂度为O(n)(由于递归调用栈)。我们首先定义链表节点结构(参考引用[1]和[3]):structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};迭代法:引用[1]中使用了以下代码:ListNode*reverseList(ListNode*head){ListNode*new_head=NULL;ListNode*next=NULL;while(head){next=head->next;//保存下一个节点head->next=new_head;//当前节点指向新的头(即反转)new_head=head;//更新新的头为当前节点head=next;//移动head到下一个节点}returnnew_head;}我们之前的迭代法实现是类似的:ListNode*reverseList(ListNode*head){ListNode*prev=nullptr;ListNode*curr=head;while(curr){ListNode*nextTemp=curr->next;curr->next=prev;prev=curr;curr=nextTemp;}returnprev;}两种方法本质相同,只是变量名不同。递归法:我们之前提供了递归实现,引用[1][2]中未提供递归法,但我们之前回答中有:ListNode*reverseListRecursive(ListNode*head){if(!head||!head->next)returnhead;ListNode*newHead=reverseListRecursive(head->next);head->next->next=head;head->next=nullptr;returnnewHead;}我们将按照以下结构组织回答:1.链表节点定义(参考引用[1]和[3])2.迭代法(参考引用[1]的代码,并添加详细注释)3.递归法(参考之前的递归实现,添加注释)4.测试示例(参考引用[1]的测试代码,但稍微简化)5.算法特性6.生成相关问题注意:引用标识。在描述迭代法时,我们参考了引用[1]的写法,因此会添加引用标识[^1];节点定义参考了引用[1]和引用[3],所以也要标注。同时,在回答末尾生成三个相关问题。由于用户要求查找使用C++实现链表逆序的相关算法或代码示例,我们提供完整的代码示例和解释。</think> ### C++ 链表逆序算法实现(原地反转) 以下是两种常见的链表逆序实现方法,均满足**原地反转**要求(空间复杂度 $O(1)$),使用以下链表节点定义: ```cpp struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }; ``` #### 📌 1. 迭代法(推荐) 时间复杂度 $O(n)$,空间复杂度 $O(1)$ ```cpp ListNode* reverseList(ListNode* head) { ListNode *prev = nullptr; ListNode *curr = head; while (curr) { ListNode *nextTemp = curr->next; // 暂存后继节点 curr->next = prev; // 反转指针指向 prev = curr; // 前移prev指针 curr = nextTemp; // 前移curr指针 } return prev; // 返回新头节点 } ``` **算法流程**: 1. 初始化 `prev = nullptr`, `curr = head` 2. 循环直到 `curr` 为空: - 暂存后继节点 `nextTemp = curr->next` - 反转指针:`curr->next = prev` - 移动指针:`prev = curr`, `curr = nextTemp` 3. 返回 `prev` (新头节点) **图解**: ``` 原始:1 → 2 → 3 → ∅ 步骤1:∅ ← 1 2 → 3 → ∅(暂存2) 步骤2:∅ ← 1 ← 2 3 → ∅(暂存3) 步骤3:∅ ← 1 ← 2 ← 3(返回3) ``` #### 📌 2. 递归法 时间复杂度 $O(n)$,空间复杂度 $O(n)$(递归栈) ```cpp ListNode* reverseListRecursive(ListNode* head) { if (!head || !head->next) return head; // 终止条件 ListNode* newHead = reverseListRecursive(head->next); head->next->next = head; // 反转相邻节点指向 head->next = nullptr; // 断开原链表连接 return newHead; } ``` **递归过程**: ``` reverse(1): → reverse(2): → reverse(3): 返回3 2.next.next=2 → 3→2 1.next.next=1 → 2→1 最终:3→2→1→∅ ``` #### 🧪 测试代码示例 ```cpp int main() { // 构建链表 1→2→3→4 ListNode a(1), b(2), c(3), d(4); a.next = &b; b.next = &c; c.next = &d; // 迭代法反转 ListNode* newHead = reverseList(&a); // 输出结果: 4→3→2→1 while (newHead) { cout << newHead->val << " → "; newHead = newHead->next; } cout << "∅" << endl; } ``` #### ⚙️ 算法特性 | 特性 | 迭代法 | 递归法 | |--------------|------------------------|------------------------| | **时间复杂度** | $O(n)$ | $O(n)$ | | **空间复杂度** | $O(1)$(常数空间) | $O(n)$(递归栈) | | **适用场景** | 长链表(无栈溢出风险) | 短链表(代码简洁) | | **核心操作** | 指针移动 | 递归回溯时反转指针 | | **边界处理** | 自动处理空链表 | 需要终止条件 | > 注:迭代法在实践中更常用,尤其适合操作系统内核开发等内存敏感场景[^1]。 --- ### 🔍 相关问题 1. 如何反转链表的指定区间(如第 $m$ 到第 $n$ 个节点)? 2. 递归反转算法的空间复杂度能否优化至 $O(1)$? 3. 如何在存在环的链表中安全执行反转操作? [^1]: 链表逆置算法 C++实现 [^2]: 单链表逆序算法 [^3]: 链表节点结构定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值