剑指offer—单链表反转的三种实现方法

Posted riotian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer—单链表反转的三种实现方法相关的知识,希望对你有一定的参考价值。

单链表的反转可以用递归、非递归和栈的方法实现

链表节点定义:

struct ListNode{
    int val;
    Node* next;
    ListNode(int x):val(x),next(nullptr){}
}

1、栈

ListNode* reverseList(ListNode* head) {
    if(!head || !head->next)
       	return head;
    stack<ListNode*>stk;
    //将链表的结点全部压进栈
    while(head){
        stk.push(head);
        head = head->next;
    }
    ListNode*cur,*nxt;
    cur = nxt = stk.top();
    stk.pop();
    while(!stk.empty()){
        nxt ->next = stk.top();
        nxt = nxt ->next;
        stk.pop();
    }
    //最后一个结点的next记得要指向nullptr
    nxt ->next =nullptr;
    return cur;
}

2、递归

利用递归,直到链表的最后一个节点,用一个指针指向该节点,作为反转后的链表的头节点
在递归返回的过程中,让该节点的下一个节点指向该节点((head->next->next=head))
并让该节点指向(NULL)。这样就从链表尾部一步步实现了反转

技术图片

Ps:图片来自网络侵权删

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

3、双指针

利用两个结点指针和一个中间结点指针 (temp(用来记录当前结点的下一个节点的位置)),分别指向当前结点和前一个结点,每次循环让当前结点的指针域指向前一个结点即可

ListNode* reverseList(ListNode* head) {
    ListNode* cur=head;
    ListNode* pre=nullptr;
    while(cur)
    {
        ListNode* tmp=cur->next;
        cur->next=pre;
        pre=cur;
        cur=tmp;
    }
    return pre;
}

以上是关于剑指offer—单链表反转的三种实现方法的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer demo之单链表反转

剑指offer系列刷题第二篇——从尾到头打印链表和反转链表

三种方法实现反转单链表

剑指 Offer 24. 反转链表

剑指 Offer 24. 反转链表

剑指OFFER 反转链表