剑指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;
}

猜你喜欢

转载自www.cnblogs.com/RioTian/p/12614568.html