• 单链表笔试题(是否相交,求交点;是否有环,求入环点)C++


    1. 判断两个单链表是否相交,若相交求交点。

    (1)首先仅判断是否相交?

    方法:令两个单链表均走到末尾,看两者尾结点是否相同即可。

    (2)判断是否相交+求交点。(此处已知单链表构造)

    方法:先让较长的链表走(两个链表长度之差)步,若两个指针不相等任一指针!=NULL就一同向后走,如果退出循环是两者相等则返回(相等的指针指向两个单链表交点);否则返回NULL。

    代码如下:

    1. struct Node
    2. {
    3. Node(int val):data(val),next(NULL){}//带参构造函数
    4. Node(){}//无参构造函数
    5. int data;
    6. Node* next;
    7. };
    8. int Get_length(Node* p)
    9. {
    10. int count = 0;
    11. while (p != NULL)
    12. {
    13. count++;
    14. p = p->next;
    15. }
    16. return count;
    17. }
    18. Node* Get_Node(Node* headA, Node* headB)
    19. {
    20. int len = Get_length(headA) - Get_length(headB);//已知headA指向的单链表较长
    21. for (int i = 0; i < len; ++i)
    22. {
    23. headA = headA->next;//较长单链表先走长度差值步
    24. }
    25. while (headA!=headB&&headA!=NULL)//两者不相等且任意一者不为空(由于两者剩余长度相同),则一同往后走
    26. {
    27. headA = headA->next;
    28. headB = headB->next;
    29. }
    30. if (headA == headB) return headA;
    31. else return NULL;
    32. }
    33. void main()
    34. {
    35. //已知较长单链表:1 2 3 5 8 9 10
    36. //已知较短单链表:4 6 9 10
    37. Node a(1), b(2), c(3), d(5), e(8), f(9), g(10);//调用带参构造函数初始化节点
    38. Node x(4), y(6);
    39. Node* headA = &a;
    40. a.next = &b;
    41. b.next = &c;
    42. c.next = &d;
    43. d.next = &e;
    44. e.next = &f;
    45. f.next = &g;
    46. Node* headB = &x;
    47. x.next = &y;
    48. y.next = &f;//令两个单链表相交
    49. Node* h = Get_Node(headA, headB);
    50. if (h != NULL)
    51. {
    52. cout << "两个单链表相交,且交点为:" << h->data << endl;
    53. }
    54. else cout << "两个单链表不相交" << endl;
    55. }

     示例:两个链表相交(如图)

      示例:两个链表不相交(如图)

    2. 判断单链表是否有环,若存在环 则返回入环点。

    (1)判断是否存在环:

    【快慢指针法】快指针fast初始化从头结点向后走两步,慢指针slow初始化走一步。while(fast!=slow&&fast!=NULL)就让fast走两步,slow走一步。若退出循环是二者相等:代表有环存在。

    注意:在while循环要判断fast!=NULL是由于如果单链表不存在环,则fast指针会先走到末尾结束循环。也保证了在while循环中fast走两步时不会出现空指针指向。

    (2)求入环点(如图)

    代码如下:

    1. struct Node
    2. {
    3. Node(int val):data(val),next(NULL){}
    4. Node(){}
    5. int data;
    6. Node* next;
    7. };
    8. Node* Get_Cir_Node(Node* head)
    9. {
    10. //快慢指针
    11. Node* fast = head->next->next;//快指针初始化走两步
    12. Node* slow = head->next;
    13. //判断是否存在环?
    14. while (fast != slow && fast != NULL)//如果单链表不存在环,则fast指针会先走到末尾结束循环。也保证了在while循环中fast走两步时不会出现空指针指向。
    15. {
    16. fast = fast->next->next;
    17. slow = slow->next;
    18. }
    19. if (fast == NULL) return NULL;
    20. //有环,找入环点:x=z+(n-1)(y+z); 距离相同,速度相同~同时相遇在入环点
    21. Node* p = head;
    22. Node* q = fast;//或者Node*q=slow; 此刻fast和slow均指向快慢指针相遇点
    23. while (p != q)
    24. {
    25. p = p->next;
    26. q = q->next;
    27. }
    28. return p;
    29. }
    30. void main()
    31. {
    32. //带环单链表:1 2 3 4 5 6 4
    33. Node a(1), b(2), c(3), d(4), e(5), f(6);
    34. Node* head = &a;
    35. a.next = &b;
    36. b.next = &c;
    37. c.next = &d;
    38. d.next = &e;
    39. e.next = &f;
    40. f.next = &d;//构成环
    41. Node* p = Get_Cir_Node(head);
    42. if (p != NULL) cout << "该单链表有环,入环点为:" << p->data << endl;
    43. else cout << "该单链表无环" << endl;
    44. }

     示例:单链表有环(如图)

     示例:单链表无环(如图)

  • 相关阅读:
    升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等
    Spring源码解读 - Spring bean 的生命周期
    SpringBoot自动装配原理
    前端在登录时将用户密码加密
    springcloud仓库管理系统源码
    列表初始化与右值引用
    简单句翻译
    网络安全常用术语
    【数据结构】红黑树
    kafka脚本总结
  • 原文地址:https://blog.csdn.net/m0_56194716/article/details/126697908