您的位置:首页 > 其它

判断两个链表是否相交,若相交,求第一个交点

2017-07-18 15:50 337 查看
首先,判断这两个链表各自是否带环。故存在下面三种情况:

1、两个链表都没带环,此时两个链表可能相交。

2、一个带环,一个不带环,则不可能相交。

3、两个都带环,判断第一个链表fast与slow相遇的结点是否在第二个链表的环中,如果在,则相交(相交时,环是两个链表公有的)

两个链表都没环,解法如下:

//判断两个无环单链表是否相交,如果两个无环但链表相交,则两个链表的最后一个结点一定相等。
bool IsCross(Node* head1, Node* head2)
{
Node* node1 = head1;
Node* node2 = head2;
if (head1 == NULL || head2 == NULL)
return false;
//找两个链表的最后一个结点
while (node1->_next != NULL)
node1 = node1->_next;
while (node2 ->_next!= NULL)
node2 = node2->_next;
if (node1 == node2)
return true;
else
return false;

}


//求链表的大小
int size(Node* head)
{
Node* node = head;
int count = 0;
if (head == NULL)
return 0;
else
{
while (node)
{
count++;
node = node->_next;
}
}
return count;
}


//两个无环单链表相交的第一个交点。先求两个链表的长度,然后求长度差len,让较长的链表先走len步,然后找相同的结点。
Node* FindNode(Node* head1, Node* head2)
{
if (head1 == NULL || head2 == NULL)
return NULL;
Node* node1 = head1;
Node* node2 = head2;
int len1 = size(head1);
int len2 = size(head2);
int len = 0;
len = len1 - len2;
if (len > 0)
{
while (len--)
{
node1 = node1->_next;
}
}
else if (len<0)
{
len = 0 - len;
while (len--)
{
node2 = node2->_next;
}
}
//len==0
while (node1 != node2)
{
node1 = node1->_next;
node2 = node2->_next;
}
return node1;
}


如果两个链表都带环,解法如下:

有两种情况,如下:

入口点相同,环内相交



入口点不同,环外相交,Y形



//找带环链表内快慢指针相遇点
Node* MeetNode(Node* head)
{
if (head == NULL)
return NULL;
Node* slow = head;
Node* fast = head->_next;
while (fast && fast->_next)
{

slow = slow->_next;
fast = fast->_next->_next;
if (slow == fast)
{
return slow;
}
}
return NULL;
}


//找带环链表的入口点
Node* EntryNode(Node* head)
{
if (head == NULL)
return NULL;
Node* slow = head;
Node* fast = head;
while (fast && fast->_next)
{
slow = slow->_next;
fast = fast->_next->_next;
if (slow == fast)
break;
}
Node* start = head;
while (start != slow)
{
start = start->_next;
slow = slow->_next;
}
return start;
}


//判断两个带环链表是否相交,若相交,求交点,否则返回空
Node*  IsHasCircle(Node* head1, Node* head2)
{
if (head1 == NULL || head2 == NULL)
return NULL;
//入口点相同,Y形,判断环外是否相交
Node* ENode1 = EntryNode(head1);
Node* ENode2 = EntryNode(head2);
Node* m1 = MeetNode(head1);
Node* m2 = MeetNode(head2);
if (ENode1 == ENode2)
{
Node* start1 = head1;
Node* start2 = head2;
while (start1 != ENode1 &&start2 != ENode2)
{
start1 = start1->_next;
start2 = start2->_next;
if (start1 == start2)
return start1;
else
return NULL;
}
}
//入口点不同,判断环内是否相交
else
{
while (m1->_next != m2)
{
if (m1 == m2)
return m1;
m1 = m1->_next;
}
if (m1 == m2)
return m1;
}
return NULL;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息