Given a singly linked list L: L 0→L 1→…→L n-1→L n,reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…
You must do this in-place without altering the nodes' values.
For example,Given{1,2,3,4}, reorder it to{1,4,2,3}.
思路:先从中间切断分为两个链表,将后一个链表反转,再逐个插入到前一个链表。
#include<iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
//链表结构定义
ListNode* reverse(ListNode *head){
ListNode* pRH = NULL;
ListNode* p = head;
ListNode* pre = NULL;
// 保持在处理每个节点时候一样,初始化NULL 第一个节点重新指向NULL
while (p != NULL){
ListNode *tmp = p->next;
if (tmp == NULL) pRH = p;
p->next = pre;
pre = p;
p = tmp;
}
return pRH;
}
// 反转链表
void reorderList(ListNode *head) {
int length = 0;
ListNode *p = head;
// 统计列表的总长度
while (p != NULL){
length++;
p = p->next;
}
int tmp = 0;
ListNode *q = head;
while (tmp < ((length - 1) / 2)){
q = q->next;
tmp++;
}
ListNode *head1 = q->next;
q->next = NULL;
ListNode *head2 = reverse(head1);
p = head;
q = head2;
// 链表从中间切断分为两个部分
while(p != NULL && q != NULL){
ListNode *tp = q->next;
q->next = p->next;
p->next = q;
if (q)
p = q->next;
q = tp;
}
// 将链表的后半部分反转后,链接到前半部分的链表
}
int main(){ //测试
int a[] = {1, 2, 3, 4, 5,6,7,8};
ListNode *head = new ListNode(a[0]);
ListNode *p = head;
for (int i = 1; i < 8; i++){
p->next = new ListNode(a[i]);
p = p->next;
}
reorderList(head);
ListNode *q = head;
while (q){
cout << q->val << endl;
q = q->next;
}
}