1,找到中间节点,并把前半部的链表以NULL结尾,
2,把后半部的链表反转,
3,前后合并两个链表
另外值得注意的是,对于中间节点的寻找,第二种方法中间总是中间位置偏后,第一种对于奇数个数的中间节点,偏前。
fast = fast->next;
if(fast){
fast = fast->next;
slow = slow->next;
}
{1 2 3 4} slow = 3
{1 2 3} slow = 2
fast = fast->next;
if(fast){
fast = fast->next;
}
slow = slow->next;
{1 2 3 4} slow = 3
{1 2 3} slow = 3
struct ListNode * reverse(struct ListNode *head)
{
if(head == NULL || head->next == NULL)
return head;
struct ListNode * prev, *curr, *next;
curr = head;
prev = next = NULL;
while(curr){
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
void reorderList(struct ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
struct ListNode *fast, *slow;
fast = head->next;
slow = head;
while(fast){
fast = fast->next;
if(fast){
fast = fast->next;
slow = slow->next;
}
}
struct ListNode *tmp = slow;
slow = slow->next;
tmp->next = NULL;
struct ListNode *front = head;
struct ListNode *back = reverse(slow);
struct ListNode *dummy = calloc(1, sizeof(struct ListNode));
struct ListNode *last = dummy;
while(1){
if(front&&back){
last->next = front;
front = front->next;
last = last->next;
last->next = back;
back = back->next;
last = last->next;
}else if(front){
last->next = front;
front = front->next;
last = last->next;
}else if(back){
last->next = back;
back = back->next;
last = last->next;
}else{
last->next = NULL;
break;
}
}
return dummy->next;
}