这个题的关键有几个点,我将分别进行分析
1.首先我们要弄清楚交换链表中两个元素的逻辑
一般来说,我们首先会想到两种思路,第一种就是第二个节点指向第一个节点,让后让第一个节点指向原来的第三个节点
第一种思路如图所示
然而这样的思路有一个问题,这样的方法会使得第一步的过程中破坏了链表的连续性,导致节点的丢失,于是我们自然而然转到另一种思路
第二种交换顺序就有效的避免了这种问题,实现了我们的目的
pre->next=j->next;
j->next=pre;
这样这题最核心的部分就解决了
这题还有一个关键的点是笔者在做时遇到的问题
运行时经常报错 member access within null pointer...
这个报错的意思是在运行时我们访问到了空指针的下一个节点
后面经过笔者的排查在两处地方发现了产生此错误的原因(应该也是大家的易错点)
一是在一开始我们就需要判断样本的特殊情况,当链表头结点或者下一个节点是空指针的情况,如果我们在赋值之后再判断就会出现在赋值阶段报错的情况。
二是在循环时快结束阶段,我们需要在pre->next的后面加上一个判断是否为null的语句,这样就能防止j访问到不存在的节点从而报错。
至此这题应该就没什么难度了,快去完成这一题吧!
AC代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
#include <stdio.h>
struct ListNode* swapPairs(struct ListNode* head) {
if (head==NULL||head->next==NULL) //这个判空语句也得在前面不然就会导致为【】时报错
return head;
struct ListNode* last=head->next;
struct ListNode* kook=head;
struct ListNode* pre=head;
//int k=1;
//while(kook->next!=NULL)
//{
// k++;
// kook=kook->next;
//printf("%d",k);
//}
//k=k/2;
//int i=1;
struct ListNode* N=NULL;
struct ListNode* j=pre->next;
// if (head==NULL)
// return head;
// if (head->next==NULL)
// return head;
while(j!=NULL)
{
pre->next=j->next;
j->next=pre;
if(N!=NULL)
{
N->next=j;
}
N=pre;
// if(pre==NULL)
// break;
pre=pre->next;
if(pre==NULL) //这个判断语句必须加在前面语句的后面不然就会导致指向空节点报错
break;
j=pre->next;
}
return last; //注意返回值应该是交换后的头结点
}