《算法通关村第二关——终于学会链表反转了!》

本文详细介绍了如何使用虚拟头节点和直接链表操作、递归方法来解决LeetCode206题的链表反转问题,展示了三种不同的实现策略。
摘要由CSDN通过智能技术生成
前言

        链表反转是一个很重要的内容,因为它不仅涉及到链表的增加,删除,对思维的能力考察也要求严格。在各类热门面试题中,处于居高不下的地位。

        本次我们探讨的是LeetCode206题:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

建立虚拟头节点辅助反转

        如上图,我们先建立应该新节点ans,使ans->next=head,在这里,我们让虚拟节点为

ans->next=node(1),之后只需要将后面的节点插入到中间对应位置即可,在这里要注意cur的移动,cur=next。即在第一步中,应为:cur->next=ans->next;ans->next=cur;cur=next;最后,我们只需要返回ans->next

struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* ans=(struct ListNode*)malloc(sizeof(struct ListNode));
    ans->next=NULL;
    struct ListNode* cur=head;
    while(cur->next!=NULL){
        struct ListNode* next=cur->next;
        cur->next=ans->next;
        ans->next=cur;
        cur=next;
    }
    return ans->next;
}
直接操作链表实现反转

        虽然利用虚拟节点操作链表反转会比较简单,但正是因为比较简单,在面试中可能不会被面试官认可,那我们怎样不利用虚拟节点进行操作呢?还是什么那一道题,我们首先根据中间过程进行分析。

        从图中我们可以看出,只需要将cur->next=pre;pre=cur;cur=next;既可以完成,下面上代码:

struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* pre=NULL;
    struct ListNode* cur=head;
    while(cur!=NULL){
        struct ListNode* next=cur->next;
        cur->next=pre;
        pre=cur;
        cur=next;
    }
    return pre;
}

        这个地方,我们从中间部分的变化更好理解。

        除了这两种方法,还有便是递归,下面我们一起来看看。

利用递归实现链表反转

        我们直接先上代码:

struct ListNode* reverseList(struct ListNode* head){
    if(head==NULL||head->next==NULL){
        return head;
    }
    struct ListNode* new_head=reverseList(head->next);
    head->next->next=head;
    head->next=NULL;
    return new_head;
}

        现在我们通过画图来理解一下这串代码的意思:由于一号节点不为空,所以new_head为2,二号节点也不为空,所以new_head为3......同理,直到五号节点的next为NULL,因此,执行  head->next->next=head;
head->next=NULL;
return new_head;此时new_head为5,而head为4,因此head->next为5,即5->next=4,之后为     4->next=NULL,这样便实现了一次反转。

下面以3->4->5为例

 可以看出head与new_head的变化,下面是整个链表的变化:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值