链表反转问题

简介: 链表反转问题

方法一

实现链表翻转最直接的方法就是:从链表的头部开始遍历每个结点,改变每个结点的指向,即将原本指向下一个结点的指针改为指向上一个结点。

遍历原链表,将结点依次插入到新链表的头部。要完成这一步操作,我们需要新添加两个指针(分别命名为 P 和 tmp):

  • P 指针用于遍历链表,并将遍历到的结点插入到新链表中;
  • tmp 指针永远指向指针 P 所在结点的下一个结点,充当原链表在每次移除头部结点后的新头指针;
List * reverse(List * H)
{
    if(H == NULL || H->next == NULL)
    {
        return H;
    }
    
    List *p = H;            //创建指针p作为遍历链表的指针
    List *newH = NULL;      //创建新链表,用于存储反转的链表  
 
    while(p != NULL)
    {
        List *tmp = p->next;
        p->next = newH;
        newH = p;
        p = tmp;
    }
    return newH;
 
}

方法二

另一种方法较前一种比较复杂,需要使用到递归的思想。


方法一是依次遍历链表,更改每个结点的指向,最后一个结点为翻转链表的头部结点。而方法二则完全倒过来,其实现过程为:先通过递归的思维找到链表的头部,然后再改变每个结点的指向,最终到达链表翻转的目的。

//链表翻转的函数
link *reverseList(link * H){
    //如果指针 H 是否存在
    if(H == NULL || H->next == NULL){
        return H;
    }
    //递归查找新链表的头,找到用赋值给 newH
    link * newH=reverseList(H->next);
    //递归完成后,H 初始状态为 NewH 的上一个结点。
    //在一步步弹栈的过程中,始终另 H 指向的结点作为新链表的最后一个结点
    H->next->next=H;
    //在链接到新链表之后,要割去 H 所指结点与下一结点的联系,否则会使新链表产生环
    H->next=NULL;
    //返回新链表所指头部的指针。
    return newH;
}


相关文章
|
7月前
|
测试技术
1025 反转链表
1025 反转链表
反转链表II
链表这部分的题,不少都离不开单链表的反转,参考:反转一个单链表 这道题加上哨兵位的话会简单很多,如果不加的话,还需要分情况一下,像是从头节点开始反转还是头节点以后开始反转,有了哨兵位后就只有一种情况了。 malloc一个哨兵位,next指向head,遍历两次,一次找起点,,开始节点的前一个节点保存下来,为了连接reverse返回的节点地址;一次找结束,结束的节点next节点保存下来,并使该节点的next指针置空,剩下的就是连接的问题,比较简单。
53 0
|
8月前
|
算法
【算法】链表反转
【算法】链表反转
34 0
|
8月前
|
C++ 索引
反转链表(C++)
反转链表(C++)
38 0
49 # 用递归和非递归两种方式实现链表反转
49 # 用递归和非递归两种方式实现链表反转
61 0
|
程序员
【Leetcode】拿捏链表(二)——21. 合并两个有序链表、876. 链表的中间结点、链表中倒数第k个结点(牛客)
【Leetcode】拿捏链表(二)——21. 合并两个有序链表、876. 链表的中间结点、链表中倒数第k个结点(牛客)
118 0
【Leetcode】拿捏链表(二)——21. 合并两个有序链表、876. 链表的中间结点、链表中倒数第k个结点(牛客)
|
存储 前端开发 程序员
实现链表反转
实现链表反转
实现链表反转
|
测试技术
「日更刷题」206. 反转链表
「日更刷题」206. 反转链表
92 0
|
算法 Java
算法打卡Day14_剑指offer22 链表中倒数第k个节点
算法打卡Day14_剑指offer22 链表中倒数第k个节点
算法打卡Day14_剑指offer22 链表中倒数第k个节点