题目:
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路:
首先找到链表中间节点的前一个节点,这里记作为mid(middlenode函数)
然后将反转mid->next,将mid之后的节点进行反转(reversenode函数)
之后让mid->next=NULL;一个链表分成了两个链表
之后进行交叉合并(mergelist函数)
先写middlenode函数找到中间节点的前一个节点,两种写法,可以使用虚拟头结点也可以不用
struct ListNode*middlenode(struct ListNode*head){
struct ListNode*dummyhead=(struct ListNode*)malloc(sizeof(struct ListNode));
dummyhead->next=head;
struct ListNode*slow=dummyhead;
struct ListNode*fast=dummyhead;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
不用的解法
struct ListNode*middlenode(struct ListNode*head){
struct ListNode*slow=head;
struct ListNode*fast=head;
while(fast->next&&fast->next->next){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
反转链表函数reversenode
struct ListNode*reversenode(struct ListNode*head){
if(head==NULL||(head->next)==NULL) return head;
struct ListNode*n1=NULL;
struct ListNode*n2=head;
struct ListNode*n3=head->next;
while(n2){
n2->next=n1;
n1=n2;
n2=n3;
if(n3) n3=n3->next;
}
return n1;
}
交叉合并函数
void mergeList(struct ListNode*cur1,struct ListNode*cur2){
struct ListNode*next1;
struct ListNode*next2;
while(cur1&&cur2){
next1=cur1->next;
next2=cur2->next;
cur1->next=cur2;
cur2->next=next1;
cur1=next1;
cur2=next2;
}
if(cur1){
cur1->next=NULL;
}
return ;
}
void reorderList(struct ListNode* head){
struct ListNode*mid=middlenode(head);
struct ListNode*rmid=reversenode(mid->next);
mid->next=NULL;
mergeList(head,rmid);
}