在链表的考查中,链表的反转是比较常见的,在此介绍几种常用的方法
题目:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
1.迭代法(双指针)
假设链表为 1→2→3→∅,把它改成 ∅←1←2←3。
在遍历链表时,将当前节点的 next 指针改为指向前一个节点。但是由于节点没有引用其前一个节点,因此必须要准备一个指针事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode*prev=NULL;
struct ListNode*curr=head;
while(curr)
{
struct ListNode*next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
return prev;
}
这里也提供python的写法,更加简便
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
cur, pre = head, None
while cur:
cur.next, pre, cur = pre, cur, cur.next
return pre
2.递归法
用递归法相比于迭代法,重要的是如何处理已经被反转的部分,即递归到第一个节点n1时,n1 的下一个节点必须指向 ∅,否则会产生环形链表
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}
提供来自官网的python写法
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
def recur(cur, pre):
if not cur: return pre # 终止条件
res = recur(cur.next, cur) # 递归后继节点
cur.next = pre # 修改节点引用指向
return res # 返回反转链表的头节点
return recur(head, None) # 调用递归并返回
3.头插法
头插法先将前面的节点断开,进行后面数据插入
typedef struct List{
int val;
struct List *next;
}List;
List*Headback(List*phead)
{
List*p=phead->next;
phead->next=NULL;
List*q;
while(p!=NULL){
q=p->next;
p->next=phead->next;
phead->next=p;
p=q;
}
return phead;
}