题目:
编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。为了简化问题,我们假设俩个链表均不带环。
问题扩展:
- 如果链表可能有环列?
- 如果需要求出俩个链表相交的第一个节点列?
解析:
流程:
1. 判断两链表是否有环
2. 若链表都不成环,判断尾结点是否相等
3.若链表都成环,判断一条链表上俩指针相遇的结点在不在另一天链表的环上
4.若一条链表成环,另一条不成环,则两链表不相交
#include <iostream>
using namespace std;
struct node
{
int data;
struct node * next;
};
typedef struct node Node;
//1.判断链表是否带环,若带环,返回环里的结点
NodeList *testCircle(NodeList *head)
{
Node *slow, *fast;
if(head == NULL)
{
return NULL;
}
slow = head;
fast = head;
while(slow != NULL && fast != NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
return slow;
}
}
}//判断一条链表上俩指针相遇的结点在不在另一天链表的环上
int isJoinedSimple(Node *head1, Node *head2)
{
if(head1 == NULL || head2 == NULL)
{
return 0;
}
while(head1->next != NULL)
{
head1 = head1->next;
}
while(head2->next != NULL)
{
head2 = head2->next;
}
return head1 == head2;
}
//判断链表是否相交
//若链表都不成环,跳到isJoinedSimple(),判断尾结点是否相等
//若链表都成环,判断一条链表上俩指针相遇的结点在不在另一天链表的环上
//若一条链表成环,另一条不成环,则两链表不相交
int isJoined(Node *head1, Node *head2)
{
Node *circle1, *circle2;
circle1 = testCircle(head1);
circle2 = testCircle(head2);
if(circle1 == NULL && circle2 == NULL)
{
return isJoinedSimple(head1, head2);
}
if(circle1 != NULL && circle2 != NULL)
{
Node * p = circle1->next;
while(p != circle1)
{
if(p == circle2)
{
return 1;
}
p = p->next;
}
}
return 0;
}
扩展1. 求存在环的链表的环入口点
NodeList *testCircle(NodeList *head)
{
Node *slow, *fast;
if(head == NULL)
{
return NULL;
}
slow = head;
fast = head;
while(slow != NULL && fast != NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
break;
}
}
if(slow == NULL || fast->next == NULL)
{
return NULL;
}
slow = head;
while(slow != fast)
{
slow = slow->next;
fast= fast->next;
}
return slow;
}
扩展2. 求两个无环链表的相交的第一个节点
1.先遍历两条链表,求出链表长度,得到长度差K;
2. 长链表先遍历k个结点,再和短链表一起遍历,两个相等的第一个结点就是所求的。