如何判断是否有交点?
两个单向链表,如果有交点,那么它们最后的一个结点必定是同一个结点。我们可以找到链表最后一个结点,比较它们是否是同一个结点。
如果两个链表有交点,如何判断交点的位置呢?
把一个链表中的每一个结点与另一个链表的中每一个结点做比较,如果找到相同的,那么这个相同的就是交点了。但是这个算法的时间复杂度为O(mn)。
如果两个链表相交,那么交点的位置到链表末端肯定相同(后面就是同一个链表了)。我们可以把两个链表以尾端为起始位置来对齐。从对齐后,依次比较每一个结点,这样算法复杂度为O(m+n)。
代码如下:
#include<iostream>
using namespace std;
class Node{
public:
int data;
Node *next;
};
//判断两个链表有无交点。其实是判断链表最后一个点是否相同
bool Judge(Node* H1,Node* H2)
{
while(H1->next)
H1=H1->next;
while(H2->next)
H2=H2->next;
return H1==H2;
}
Node* FindNode(Node* H1,Node* H2)
{
int L1=0;//H1长度
int L2=0;//H2长度
Node* Head1=H1;
Node* Head2=H2;
while(H1){
L1++;
H1=H1->next;
}
while(H2){
L2++;
H2=H2->next;
}
if(L1>L2)
{
for(int i=0;i<L1-L2;i++)
Head1=Head1->next;
}
if(L2>L1)
{
for(int i=0;i<L2-L1;i++)
Head2=Head2->next;
}
while(Head1!=Head2){
Head1=Head1->next;
Head2=Head2->next;
}
return Head1;
}
int main()
{
Node* Head1=new Node();
Head1->data=0;
Node* Head2=new Node();
Head2->data=0;
Node* current=Head1;
//构建链表1
for(int i=1;i<9;i++)
{
current->next=new Node();
current->next->data=i;
current->next->next=NULL;
current=current->next;
}
//构建链表2
current=Head2;
for(int i=1;i<3;i++)
{
current->next=new Node();
current->next->data=i;
current->next->next=NULL;
current=current->next;
}
//连接两个链表
current->next=Head1->next->next;
bool test=Judge(Head1,Head2);
Node* common=NULL;//交点
if(test)
common=FindNode(Head1,Head2);
//释放内存
current=Head1;
while(current!=common)
{
Head1=Head1->next;
delete current;
current=Head1;
}
current=Head2;
while(current!=common)
{
Head2=Head2->next;
delete current;
current=Head1;
}
current=common;
while(current)
{
common=common->next;
delete current;
current=common;
}
return 0;
}
最后在释放内存时要注意,如果像普通单向链表那样释放,会造成交点内存释放两次,以及交点后面内存释放的不确定性。