题目: 设线性表L=(a1,a2,a3,...,an-2,an-1,an),采用带头结点的单链表保存,设计一个空间复杂度为O(1)的
算法,得到L'=(a1,an,a2,an-1,a3,an-2...)
分析:
这道题还是有一点复杂的,不过我们慢慢分析它。我们可以这样来操作,我们设置两个指针slow和fast,其中fast每次走两步,
slow每次走一步,当fast到达链尾时,slow刚好处于链表中间节点,之前我们学过链表逆置,接下来我们把slow后面的节点逆置,
链表就变成了(a1,a2,a3,...,an,an-1,an-2,...),然后我们从中间开始遍历,依次将节点插入到前面节点后面,即可完成要求。
代码如下:
struct Link {
union {
int data;
}type;
struct Link *next;
};
#include <stdlib.h>
#include <stdio.h>
void crossTheLink(Link *h) {
void reverse(Link *);
struct Link *fast = h->next, *slow = h->next,*mid;
mid = (struct Link*)malloc(sizeof(struct Link));
while (fast->next&&fast->next->next) {//寻找中间节点
fast = fast->next->next;
slow = slow->next;
}
mid->next = slow->next;
reverse(mid);//逆转mid后面的节点
slow->next = mid->next;
fast = h->next;
slow->next = NULL;
slow = mid->next;
while (slow) {//逐个进行插入
mid = slow->next;
slow->next = fast->next;
fast->next = slow;
slow = mid;
fast = fast->next->next;//因为将slow插入了,所以之前的fast下一个是现在的下两个
}
}
void reverse(Link *h) {
struct Link *p = h->next,*r;
h->next = NULL;
while (p) {
r = p->next;
p->next = h->next;
h->next = p;
p = r;
}
}
int main() {
struct Link *head,*p;
Link *createLink(int);
head = createLink(0);
crossTheLink(head);
printf("交叉后的链表为:");
p = head->next;
while (p) {
printf("%d ", p->type.data);
p = p->next;
}
return 0;
}
遇到困难时不要抱怨,既然改变不了过去,那么就努力改变未来。