单链表翻转

一、节点的定义

struct ListNode{  
    int val;  
    ListNode* next;  
    ListNode(int a):val(a),next(NULL){}  
};  

二、 翻转的方法

1、就地反转法

把当前链表的下一个节点pCur插入到头结点dummy的下一个节点中,就地反转。

dummy->1->2->3->4->5的就地反转过程:

dummy->2->1->3->4->5

dummy->3->2->1->4->5

dummy->4>-3->2->1->5

dummy->5->4->3->2->1

单链表翻转_第1张图片

 

过程:

  1. prev连接下一次需要反转的节点
  2. 反转节点pCur
  3. 纠正头结点dummy的指向
  4. pCur指向下一次要反转的节点
  5. 单链表翻转_第2张图片
// 1.就地反转法
    public ListNode* reverseList1(ListNode* head) {
        if (head == nullptr)
            return head;
        ListNode* dummy = new ListNode(-1);//新建一个头结点
        dummy->next = head;
        ListNode* prev = dummy->next;//下一次要反转的节点
        ListNode* pCur = prev->next;//当前要反转的节点
        while (pCur != nullptr) {
            prev->next = pCur->next;
            pCur->next = dummy->next;
            dummy->next = pCur;
            pCur = prev->next;
        }
        return dummy->next;
    }

2、递归

因为发现大部分问题都可以从递归角度想想,所以这道题目也从递归角度想了想。

现在需要把A->B->C->D进行反转,
可以先假设B->C->D已经反转好,已经成为了D->C->B,那么接下来要做的事情就是将D->C->B看成一个整体,让这个整体的next指向A,所以问题转化了反转B->C->D。那么,
可以先假设C->D已经反转好,已经成为了D->C,那么接下来要做的事情就是将D->C看成一个整体,让这个整体的next指向B,所以问题转化了反转C->D。那么,
可以先假设D(其实是D->NULL)已经反转好,已经成为了D(其实是head->D),那么接下来要做的事情就是将D(其实是head->D)看成一个整体,让这个整体的next指向C,所以问题转化了反转D。
上面这个过程就是递归的过程,这其中最麻烦的问题是,如果保留新链表的head指针呢?想到了两个办法。

 1)使用一个成员变量m_phead

class Solution{  
     ListNode* reverseLinkedList4(ListNode* head){ //输入: 旧链表的头指针  
        if(head==NULL)  
            return NULL;  
        if(head->next==NULL){  
            m_phead=head;  
            return head;  
        }  
        ListNode* new_tail=reverseLinkedList4(head->next);  
        new_tail->next=head;  
        head->next=NULL;  
        return head; //输出: 新链表的尾指针  
     }  
    ListNode* m_phead=NULL;//member variable defined for reverseLinkedList4(ListNode* head)  
};  

2) 增加一个引用型参数 new_head,它用来保存新链表的头指针。

class Solution{  
    ListNode* reverseLinkedList5(ListNode* head, ListNode* & new_head){ //输入参数head为旧链表的头指针。new_head为新链表的头指针。  
        if(head==NULL)  
            return NULL;  
        if(head->next==NULL){  
            new_head=head; //当处理到了旧链表的尾指针,也就是新链表的头指针时,对new_head进行赋值。因为是引用型参数,所以在接下来调用中new_head的值逐层传递下去。  
            return head;  
        }  
        ListNode* new_tail=reverseLinkedList5(head->next,new_head);  
        new_tail->next=head;  
        head->next=NULL;  
        return head; //输出参数head为新链表的尾指针。  
    }  
};  

 参考:

https://www.cnblogs.com/mwl523/p/10749144.html

https://www.cnblogs.com/mafeng/p/7149980.html

 

 

你可能感兴趣的:(LeetCode)