# 2019年全国研究生入学考试计算机学科专业基础综合(408)数据结构编码题

struct Node {
int data;
Node *next;
}


• 把单向链表分成两部分，$(a_1,a_3,\dots,a_{n-1})$$(a_2,a_4,\dots,a_{n})$
• 头插法逆转$(a_2,a_4,\dots,a_{n})$，变成$(a_n,a_{n-2},\dots,a_{2})$
• 合并这两部分。

Node *reverse(Node *root)
{
// 少于等于2个结点直接返回
if (root == NULL || root->next == NULL || root->next->next == NULL)
return root;
Node *listA = root, *listB = root->next;
// 1 : 分离
Node *pa = listA, *pb = listB;
for (; pb->next != NULL; ) {
pa->next = pa->next->next;
pa = pa->next;
pb->next = pa->next;
pb = pb->next;
}
pa->next = NULL;
// 2 : 头插法
pb = listB->next;
listB->next = NULL;
for (Node *p = pb; p != NULL; ) {
Node *tn = p->next;
p->next = listB;
listB = p;
p = tn;
}
// 3 : 合并
pa = listA, pb = listB;
for ( ; pb != NULL; ) {
Node *ta = pa->next, *tb = pb->next;
pa->next = pb;
pb->next = ta;
pa = ta;
pb = tb;
}
return listA;
}


int main()
{
root->next = NULL;
for (int i = 1; i < 11; ++i) {
root->next = new Node;
root->next->data = i;
root = root->next;
root->next = NULL;
}
for (Node *p = head.next; p != NULL; p = p->next)
printf("%d ", p->data);
puts("");

for (Node *p = head.next; p != NULL; p = p->next)
printf("%d ", p->data);
puts("");
return 0;
}


PS C:\Users\FlushHip\Desktop\TTT> .\a.exe
1 2 3 4 5 6 7 8 9 10
1 10 3 8 5 6 7 4 9 2
PS C:\Users\FlushHip\Desktop\TTT>