题目描述:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点
//头结点定义
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
思路:对于链表逆置,最常用的方法就是一直头插了和反转节点的next了,这两种方法又分别有两种情况,链表有头结点和链表无头结点。一直头插:一直头插就是将原有链表的节点从前到后一个一个拆下来再重新连接到到头结点上,因为先插的节点总是在链表后边,所以重新头插完之后,链表就形成逆置了。
方法一:一直头插图解(无头结点):
代码实现
ListNode* reverseList(ListNode* head) {
ListNode* p = head;
ListNode* s = NULL;
head = NULL;
while (p != NULL)
{
s = p;
p = p->next;
s->next = head;
head = s;
}
return head;
}
有头结点:
代码实现:
ListNode* Reverse(ListNode* p)
{
assert(p != NULL);
if (p == NULL && p->next == NULL)
{
return p;
}
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
head->next = NULL;
while (p != NULL)
{
ListNode* s = p;
p = p->next;
s->next = head->next;
head->next = s;
}
p = head->next;
free(head);
return p;
}
方法二:反转链表的next域图解(无头结点):
代码实现:
ListNode* reversePrint(ListNode* head)
{
ListNode *p=NULL;
ListNode *q=head->next;
ListNode *r=head->next;
head->next=NULL;
while(r->next!=NULL)
{
q->next=p;
p=q;
q=r;
r=r->next;
}
return head;
}
有头结点代码实现:
ListNode* reversePrint(ListNode* head)
{
ListNode *p=NULL;
ListNode *q=head->next->next;
ListNode *r=head->next->next;
head->next->next=NULL;
head->next=NULL;
while(r->next!=NULL)
{
q->next=p;
p=q;
q=r;
r=r->next;
}
head->next=q;
return head->next;
}
方法三:递归逆置:
ListNode* RevList(ListNode* pre, ListNode* p)
{
ListNode* tail = NULL;
if (p != NULL)
{
tail = RevList(p, p->next);
p->next = pre;
}
else
{
tail = pre;
}
return tail;
}