44.png

    1. /*
    2. 设线性表L=(a1,a2,a3,...,an-2,an-1,an),采用带头结点的单链表保存,设计一个空间复杂度为O(1)的
    3. 算法,得到L'=(a1,an,a2,an-1,a3,an-2...)
    4. 分析:
    5. 这道题还是有一点复杂的,不过我们慢慢分析它。我们可以这样来操作,我们设置两个指针slow和fast,其中fast每次走两步,
    6. slow每次走一步,当fast到达链尾时,slow刚好处于链表中间节点,之前我们学过链表逆置,接下来我们把slow后面的节点逆置,
    7. 链表就变成了(a1,a2,a3,...,an,an-1,an-2,...),然后我们从中间开始遍历,依次将节点插入到前面节点后面,即可完成要求
    8. */
    9. struct Link {
    10. union {
    11. int data;
    12. }type;
    13. struct Link *next;
    14. };
    15. #include <stdlib.h>
    16. #include <stdio.h>
    17. void crossTheLink(Link *h) {
    18. void reverse(Link *);
    19. struct Link *fast = h->next, *slow = h->next,*mid;
    20. mid = (struct Link*)malloc(sizeof(struct Link));
    21. while (fast->next&&fast->next->next) {//寻找中间节点
    22. fast = fast->next->next;
    23. slow = slow->next;
    24. }
    25. mid->next = slow->next;
    26. reverse(mid);//逆转mid后面的节点
    27. //slow->next = mid->next;
    28. fast = h->next;
    29. slow->next = NULL;
    30. slow = mid->next;
    31. while (slow) {//逐个进行插入
    32. mid = slow->next;
    33. slow->next = fast->next;
    34. fast->next = slow;
    35. slow = mid;
    36. fast = fast->next->next;//因为将slow插入了,所以之前的fast下一个是现在的下两个
    37. }
    38. }
    39. void reverse(Link *h) {//头插法逆置
    40. struct Link *p = h->next,*r;
    41. h->next = NULL;
    42. while (p) {
    43. r = p->next;
    44. p->next = h->next;
    45. h->next = p;
    46. p = r;
    47. }
    48. }
    49. int main() {
    50. struct Link *head,*p;
    51. Link *createLink(int);
    52. head = createLink(0);
    53. crossTheLink(head);
    54. printf("交叉后的链表为:");
    55. p = head->next;
    56. while (p) {
    57. printf("%d ", p->type.data);
    58. p = p->next;
    59. }
    60. return 0;
    61. }