通常情况下,不带环的两个链表相交如上图所示。
方法一:<1>先判断链表是否相交
①若相交,那么两个链表的尾节点必然相同。则可以遍历两个链表,判断其尾节点。
②若不相交,则尾节点必然不相同。
<2>若相交,求其入口点
①通过遍历两个链表可以得到其长度(假设为len1和len2),通过比较len(len=abs(len1-len2)),让长的链表先走len步,然后两个链表同时走,当他们遇到第一个相等的节点的时候,即为其入口点。
//判断两链表是否相交
typedef struct ListNode
{
int _data;
ListNode *_next;
}Node;
bool IsCrossList(Node *head1 , Node *head2) //判断两个链表是否相交
{
if (head1 == NULL || head2 == NULL || head1->_next == NULL || head2->_next == NULL)
{
return false;
}
while (head1)
{
head1 = head1->_next;
}
while (head2)
{
head2 = head2->_next;
}
return head1 == head2 ? true : false;
}
//判断链表的入口点
Node *CrossNode(Node *head1,Node *head2)
{
Node *cur1 = head1;
Node *cur2 = head2;
size_t len = 0;
size_t len1 = 0;
size_t len2 = 0;
while (cur1)
{
cur1 = cur1->_next;
++len1;
}
while(cur2)
{
cur2 = cur2->_next;
++len2;
}
len = abs(len1 - len2);
if (len1>len2)
{
for (size_t i=0;i<len;i++)
{
head1 = head1->_next;
}
}
else
{
for (size_t i=0;i<len;i++)
{
head2 = head2->_next;
}
}
while (head1 != head2)
{
head2 = head2->_next;
head1 = head1->_next;
}
return head1;
}
方法二:直接建立两个栈,把链表放入栈中,遵循先进后出原则,尾节点先出,即可判断是否相交。出栈的最后一个相同节点即为入口点。
Node *CrossNode(Node *head1,Node *head2)
{
if (head1 == NULL || head2 == NULL)
{
return NULL;
}
stack<Node*> s1;
stack<Node*> s2; //创建两个栈
Node *cur1 = NULL;
Node *cur2 = NULL;
while (head1 != NULL)
{
cur1 = head1;
s1.push(cur1);
head1 = head1->_next;
}
while (head2 != NULL)
{
cur2 = head2;
s2.push(cur2);
head2 = head2->_next;
}
if (cur1 == cur2)
{
Node *ret = NULL;
while(s1.top() == s2.top())
{
ret = s1.top();
s1.pop();
s2.pop();
}
return ret;
}
else
{
return NULL;
}
}