判断两个链表是否相交
0 问题
判断两个单链表是否相交,(拓展一下就是,如果相交,那么节点在哪?)
1 开场白
因为是单链表,可以看出每个节点只有一个后继节点,所以只存在两个链汇成一个链,不会存在两个链在一点交织,然后分散成两个链,所以问题的求解就与习题4-4,寻找相同后缀的问题基本类似了
2 算法介绍
2.0 数据结构
typedef struct LNode{
int data;
LNode *next;
}*LinkList, LNode;
//且具有头结点!
2.1 利用hash表
因为每个节点的地址是对此节点的唯一标识,所以,可以将第一个单链表的每个节点的地址存入hash表中;然后依次判断第二个单链表的每个节点地址与hash表中节点地址是否相同
2.2 实现题意的判断并不找出相交点(实现)
如果两个链表相交则必然最后一个节点相同,所以可以提前判断最后一个节点。
int base_judge(LinkList l1, LinkList l2){
LNode *p, *q;
p = l1;
q = l2;
while(p->next != nullptr) p = p->next;
while(q->next != nullptr) q = q->next;
if(q == p) return 1;
else return 0;
}
2.2 利用栈判断以及找出相交点(实现)
很容易想到的一个方法,就是利用栈的特性(先进后出),将两个链表的每个节点都压进栈,如果第一次弹出的节点相同,则证明两个单链表必然相交,然后逐个弹出比较,最终找到最后一个相等的节点;相反,如果第一个节点就不相同,则说明两个单链表没有相交的。
LNode* stack_judge(LinkList l1, LinkList l2){
stack<LNode*> s1, s2;
LNode *p, *q;
p = l1;
q = l2;
while(p->next) {
s1.push(p);
p = p->next;
}
while(q->next) {
s2.push(q);
q = q->next;
}
LNode *currentSame = nullptr;
while(!s1.empty() && !s2.empty()){
LNode* tmp1, *tmp2;
tmp1 = s1.top();
tmp2 = s2.top();
s1.pop();
s2.pop();
if(tmp1 == tmp2){
currentSame = tmp1;
}else{
break;
}
}
return currentSame;
}
2.3 利用环判断以及找出相交点(实现)
这个方法,一开始真的没有想到,看了博客上的这种解法,感觉很巧妙。即将第一个单链的末尾连上第二个单链的第一个节点(非头结点)
可以通过判断是否为环,来判断两个单链表是否相交!
LNode* circle_judge(LinkList l1, LinkList l2){
LNode *saveL1 = nullptr;
LNode *p = l1;
LNode *q = l2;
while(p->next) p = p->next;
saveL1 = p;
//因为头结点的存在
p->next = q->next;
Print_Circle(l1, 15);
LNode* start = Return_Start_Circle(l1);
saveL1->next = nullptr;
return start;
}
2.4 利用长度差判断以及找出相交点(实现)
将长的链表移动(长链表-短链表)个距离,然后同时移动,直到找到第一个相同的节点。
当然如果只需要判断是否相交,则可以直接都移动到最后一个节点,判断是否相同。
LNode* len_judge(LinkList l1, LinkList l2){
int len1 = 0, len2 = 0;
int difference = 0;
LNode *p, *q;
p = l1;
q = l2;
while(p->next){
len1 ++;
p = p->next;
}
while(q->next){
len2 ++;
q = q->next;
}
if(q != p) return nullptr;
if(len1 > len2){
difference = len1 - len2;
p = l1;
while(difference--){
p = p->next;
}
q = l2;
}else{
difference = len2 - len1;
q = l2;
while(difference --){
q = q->next;
}
p = l1;
}
while(p->next){
if(p == q) break;
p = p->next;
q = q->next;
}
return p;
}