编写一个程序,找到两个单链表相交的起始节点。考虑到各种情况。链表为无头结点、单向、不循环。(由于涉及到结构体,所以写不了完整的测试代码,下面展示的代码为LeetCode中写的代码)

//第一次尝试:
//方法一:计数遍历,由于链表a、b长短不一,所以先遍历计数一遍,a的长度记为counta,b的长度记为countb,然后让长的链表先走|counta-countb|个节点,此时a、b就一样长了
// 然后a、b同时遍历,若有相交节点,则a=b,若没有,则会走到NULL,然后返回即可
//方法二:(参考了一下大佬的思路)双指针,我们先来看一下这样两个链表,a=[0,2,6,8,6.2],b=[5,3,4,9,7,8,6,2],a、b里面从元素8开始相交;现在记a、b中没相交的部分分别为aa、bb,相交部分为ab
// 那么我们可以得到aa+ab+bb==bb+ab+aa,也就是说,遍历a、b,a遍历结束就跳到b的头结点接着遍历,b遍历结束就跳到a的头结点接着遍历,那么若有交点,则会定会有a==b
// 下面画个图解释一下吧:

struct
ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) { if(headA == NULL||headB == NULL){ return NULL; } //计数遍历 struct ListNode* a = headA; struct ListNode* b = headB; int counta = 0; int countb = 0;
//计数,a、b有多少个节点
while(a||b){ if(a){ a = a->next; counta++; } if(b){ b = b->next; countb++; } } int count = 0;
//让节点多的先走|counta-countb|步,此时二者剩余长度相同
if(counta - countb > 0){ count = counta - countb; while(count--){ headA = headA->next; } } else{ count = countb - counta; while(count--){ headB = headB->next; } }
//找相同的节点
while((headA != headB)&&headA&&headB){ headA = headA->next; headB = headB->next; }
//如果没有交点,那么headA==headB==NULL,若果有交点headA==headB==相交的第一个节点
return headA; //双指针(参考了大佬的思路) struct ListNode* pa = headA; struct ListNode* pb = headB; int flag = 0;
//循环遍历
while(pa != pb&&flag != 2){ if(pa){ pa = pa->next; } else{
       //设置flag标志位的目的是,若果没有交点,防止死循环,因为else这一步最多执行一次,执行过一次之后,若还没找到相交的,则说明没有交点
       flag
++; pa = headB; } if(pb){ pb = pb->next; } else{ pb = headA; } } return flag == 2 ? NULL : pa; }