您的位置:首页 > 编程语言

7.微软亚院之编程判断俩个链表是否相交(如果需要求出俩个链表相交的第一个节点)

2012-11-27 20:09 489 查看
问题:

微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:

2.如果需要求出俩个链表相交的第一个节点列?

答案:
参考文章:http://blog.csdn.net/lihappy999/article/details/7330175

//20121127
#include <iostream>
using namespace std;

typedef struct node
{
int num;
node* next;
}node;
void generateList(const bool circleTrue,node *&head1,node *&head2);
//产生链表,两个链表相交,circleTrue 为true表示产生环,false为不带环
//产生的链表结构肯定是相同的
bool judgeCircle(node* const head);//判断是否存在环,true存在,false不存在
node* crossNode(const bool circleTrue,node *head1,node *head2);
int main()
{
node* head1;
node* head2;
generateList(true,head1,head2);//相交,且有环
bool b=judgeCircle(head1);
node* p=crossNode(b,head1,head2);
cout<<"cross node:"<<p->num<<endl;
return 0;
}
void generateList(const bool circleTrue,node *&head1,node *&head2)
{
//每个链表都具有10个节点
node *pre1=NULL;
node *p=new node;
head1=p;
p->num=rand();
p->next=NULL;
pre1=p;

node *pre2=NULL;
p=new node;
head2=p;
p->num=rand();
p->next=NULL;
pre2=p;

//假设从第3个节点开始相交
int crossID=3;
//假设环的开始节点为5
int circleStart=5;
node *cs1=NULL;
node *cs2=NULL;

for (int i=0;i<10;++i)
{
//第一条链表的节点
p=new node;
pre1->next=p;
p->num=rand();
p->next=NULL;
pre1=p;
if (i==circleStart)
{
cs1=p;
}
if (i==crossID)
{
cs2=p;
}
}
if (circleTrue)
{
pre1->next=cs1;
}

for (int i=0;i<5;++i)
{
p=new node;
pre2->next=p;
p->num=rand();
p->next=NULL;
pre2=p;
}
pre2->next=cs2;
}

bool judgeCircle(node* const head)
{
//两个指针,一个每次走一步,一个每次走两步,当前一个指针赶上后一个指针时,就说明存在环
node* p1=head;
node* p2=head;
while ((p1->next!=NULL)&&(p2->next!=NULL))
{
p1=p1->next;
p2=p2->next->next;
if (p1==p2)
{
break;
}
}
if (p2->next==NULL)
{
return false;
}
else
{
return true;
}
}
node* crossNode(const bool circleTrue,node *head1,node *head2)
{

if (!circleTrue)
{
//不存在环
int num1=1;
int num2=1;
node* p1=head1;
node* p2=head2;
while (head1->next!=NULL)
{
num1++;
head1=head1->next;
}
while (head2->next!=NULL)
{
num2++;
head2=head2->next;
}
int preNum=num1>=num2?num1-num2:num2-num1;//对齐处理
if (num1>=num2)
{
for (int i=0;i<preNum;i++)
{
p1=p1->next;
}
}
else
{
for (int i=0;i<preNum;i++)
{
p2=p2->next;
}
}
while (p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
return p1;
}
else
{
//存在环
//分两种情况,入环口相同和入环口不同
node* p1=head1;
node* p2=head1;
p1=p1->next;
p2=p2->next->next;
while (p1!=p2)
{
p1=p1->next;
p2=p2->next->next;
}
//相遇点p2
p1=head1;
node* entraNode;
while (p1!=p2)
{
p1=p1->next;
entraNode=p2;
p2=p2->next;
}
//相遇点p1的前一点pre即为环的入口点

p1=head1;
p2=head2;
int num1=0;
while (p1->next!=entraNode)
{
num1++;
p1=p1->next;
}
int num2=0;
while (p2->next!=entraNode)
{
num2++;
p2=p2->next;
}
p1=head1;
p2=head2;
int preNum=num1>=num2?num1-num2:num2-num1;//对齐处理
if (num1>=num2)
{
for (int i=0;i<preNum;i++)
{
p1=p1->next;
}
}
else
{
for (int i=0;i<preNum;i++)
{
p2=p2->next;
}
}
while (p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
return p1;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表
相关文章推荐