41.png

    1. /*
    2. 存在这样一种情况,如果两个单词有相同的后缀,那我们可以将后缀作为公共部分存储,比如being和loading,其中ing就可以作为
    3. 公共部分,现在存在两个链表,含有公共部分,设计一个高效算法找到其公共后缀其实位置。
    4. 分析:
    5. 我们可以这样想,如果我们单纯的让两条链表的指针同步移动,那么只有两条链表长度相同时才可能在公共部分的起始位置相遇,
    6. 所以我们应该让他们处于同一起跑线上,故而我们应该让较长的链表先走,具体走多少,应该是走过两条链表的长度之差。
    7. */
    8. struct Link {
    9. union
    10. {
    11. int data;
    12. char letter;
    13. };
    14. Link *next;
    15. };
    16. #include <stdio.h>
    17. #include <stdlib.h>
    18. Link *findCommonSuffix(Link *h1,Link *h2) {
    19. struct Link *p = h1->next, *q = h2->next;
    20. int countP =0, countQ = 0,gap;
    21. while (p) {//遍历,获取链表长度
    22. countP++;
    23. p = p->next;
    24. }
    25. while (q) {
    26. countQ++;
    27. q = q->next;
    28. }
    29. if (countQ>countP) {//让p指针始终指向较长的那条链表
    30. p = h2->next;
    31. q = h1->next;
    32. gap = countQ - countP;
    33. }
    34. else {
    35. p = h1->next;
    36. q = h2->next;
    37. gap = countP - countQ;
    38. }
    39. while (gap--) p = p->next;//长链表指针先行移动gap位
    40. while (q != p && q != NULL) {//当两指针不同或不为NULL时继续向后移动
    41. q = q->next;
    42. p = p->next;
    43. }
    44. return p;
    45. }
    46. int main() {
    47. struct Link *h1,*h2,*com,*p1,*p2,*start;
    48. Link *createLink(int);
    49. char p[] = "letter";//数据类型,char
    50. h1 = createLink(1);
    51. h2 = createLink(1);
    52. com = createLink(1);//公共部分
    53. p1 = h1->next;
    54. p2 = h2->next;
    55. while (p1->next)p1 = p1->next;//到达链尾
    56. while (p2->next)p2 = p2->next;
    57. p1->next = com->next;//链接公共部分
    58. p2->next = com->next;
    59. p1 = h1->next;
    60. p2 = h2->next;
    61. while (p1) {
    62. printf("%c",p1->letter);
    63. p1 = p1->next;
    64. }
    65. printf("\n");
    66. while (p2) {
    67. printf("%c",p2->letter);
    68. p2 = p2->next;
    69. }
    70. printf("\n");
    71. start=findCommonSuffix(h1,h2);
    72. printf("%c",start->letter);
    73. return 0;
    74. }