链表 24.两两交换链表中的节点
题目
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。给定 1->2->3->4, 你应该返回 2->1->4->3.
给定 1->2->3->4->5, 你应该返回 2->1->4->3->5.
分析
我第一个想到的思路不是递归而是迭代,但还是觉得递归比较简单。递归:首先要先想出递归公式,根据题意是要交换相邻的节点。
first->next = swapPairs(second->next);
second->next = first;
1、第一个节点的next指针要指向第二个节点的下一个节点。
2、第二个节点的next指针要指向第一个节点。
1和2的顺序不能换,为啥?因为先执行2,second->next就会丢失,这样1也会执行错误
返回值,因为节点两两交换,自然应当返回交换之后的头结点。
递归出口
if( NULL == head || NULL == head->next )
{
return head;
}
这样,问题也就解决了。
代码实现
递归
struct ListNode* swapPairs(struct ListNode* head){
if( NULL == head || NULL == head->next )
{
return head;
}
struct ListNode *first = head;
struct ListNode *second = head->next;
first->next = swapPairs(second->next);
second->next = first;
return second;
}
迭代
struct ListNode* swapPairs(struct ListNode* head){
//head为NULL的情况
if( NULL == head ) return head;
struct ListNode *temp;
struct ListNode *p,*q,*old;
old = p = head; //指向头结点
q = head->next; //指向头结点的下一个节点
while( q != NULL && p != NULL )
{
temp = q;
p->next = q->next;/*节点1指向节点3*/
q->next = p;/*节点2指向节点1*/
if( p==head )
{
head = temp;
}
else
{
old->next = temp;
}
old = p;
//指向下一段要交换的节点
p = p->next;
if( p == NULL )/*若p=NULL,q在p后面一定是NULL*/
{
q = NULL;
}
else
{
q = p->next;
}
}
return head;
}
纸上得来终觉浅,绝知此事要躬行