题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。例如:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
思路1:(递归
链表自带的天然的递归属性使得链表题通常都可以用递归的方法进行解决,递归的思想真的有时候很奇妙,一个先递再归的过程,只关注局部问题,从局部到整体的思想展现的很好。这个题的递归思路很简单,我们设置一个newhead的指针,用于存放交换后的新节点。具体的详细思路在代码段内展现。
**
* Definition for singly-linked list.
//下面不用说就是链表结构体的构造
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head){
//首先我们要明确一点,递归的过程总是先遍历链表到一个链表的尽头,然后再
倒着往回走。所以写递归的代码我们首先就要确定一个判定值。这里我们又要考
虑两点,链表的节点数是奇数还是偶数呢,所以有两种情况,一种是遍历到最后
一个节点,一种是遍历到最后一个节点的后面一个节点,也就是一个null。所以
条件分为两种。
if(head==NULL||head->next==NULL){
return head;
}
//想要写出一段递归的代码其实可以先在脑袋里面先模拟一下递归的过程,防止
上面的限制条件出现纰漏,然后就是递归最重要的 “只关心局部问题” 拿上面的
例子做示范,首先把newhead赋值成head->next。然后把此时放到newhead的
下一个节点head的下一个节点确定,就可以写出head->swap.....
struct ListNode *NewHead=head->next;
head->next=swapPairs(NewHead->next);
NewHead->next=head;
return NewHead;
}
思路2:(哑节点迭代
其实这个方法相对于递归来说就没有那么巧妙了,就很很简单的思路,创建一个节点,用来过度,用来交换节点位置,其他没什么特别的地方,具体思路看代码段。
代码段:
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head){
//这里不像之前创造一个结构体指针,创建结构体指针一般是就只起到
指向性功能,然后移动指针从而在节点里面改变节点值什么的。这里创造
的是一个哑节点,目的是接收节点,从而起到交换节点位置的作用。
struct ListNode dummyhead;
dummyhead.next=head;
struct ListNode* tmp=&dummyhead;
//同样要考虑节点数奇数偶数的情况,所以有两种情况要同时满足
while(tmp->next!=NULL&&tmp->next->next!=NULL){
//一共三个指针,相当于三个节点的指针域,通过改变指针域的指向来改变
节点的位置,从而实现节点交换
struct ListNode* node1=tmp->next;
struct ListNode* node2=tmp->next->next;
//这里唯一要注意的就是这个交换过程,不要想多的,注意节点指针域指向位置
然后再进行交换就ok了
tmp->next=node2;
node1->next=node2->next;
node2->next=node1;
tmp=node1;
}
return dummyhead.next;
}