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

7.微软亚院之编程判断俩个链表是否相交(如果链表可能有环)

2012-11-25 17:26 549 查看
问题:

微软亚院之编程判断俩个链表是否相交

给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?

答案:

//20121125
#include <iostream>

using namespace std;

typedef struct node
{
int num;
node* next;
}node;
void generateList(const bool cross,const bool circleTrue1,const bool circleTrue2,node *&head1,node *&head2);
//产生带环的链表,cross  true代表相交,false代表不相交
//circleTrue1  true代表第一个链表有环,false代表没有环
//circleTrue2  true代表第二个链表有环,false代表没有环
//如果circleTrue1==circleTrue2 为false,那么cross必须为false
bool judgeCircle(node* const head);//判断是否存在环,true存在,false不存在
bool judgeCross(node *head1,node *head2,const bool cross);
//cross  true表示存在环,false表示不存在环
int main()
{
node* head1;
node* head2;
generateList(true,true,true,head1,head2);
bool cir1=judgeCircle(head1);
bool cir2=judgeCircle(head2);
if (cir1==cir2)
{
//结构相同,可能相交
bool judge=judgeCross(head1,head2,cir1);
if (judge)
{
cout<<"cross true!"<<endl;
}
else
{
cout<<"cross false!"<<endl;
}
}
else
{
//结构不同,不可能相交
cout<<"cross false!"<<endl;
}
return 0;
}
void generateList(const bool cross,const bool circleTrue1,const bool circleTrue2,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;

if (cross)
{
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 (circleTrue1&&circleTrue2)
{
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;
}
else
{
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 (circleTrue1)
{
pre1->next=cs1;
}

for (int i=0;i<10;++i)
{
//第二条链表的节点
p=new node;
pre2->next=p;
p->num=rand();
p->next=NULL;
pre2=p;
if (i==circleStart)
{
cs2=p;
}
}
if (circleTrue2)
{
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;
}
}

bool judgeCross(node *head1,node *head2,const bool cross)
{
if (cross)
{
node* p1=head1;
while (1)
{
head1=head1->next;
p1=p1->next->next;
if (p1==head1)
{
break;
}
}

node* p2=head2;
while (1)
{
head2=head2->next;
p2=p2->next->next;
if (p2==head2)
{
break;
}
}

node* p3=p1;
p1=p1->next;
bool circleTrue=false;
while(1)
{
if (p1==p2)
{
circleTrue=true;
break;
}
if (p1==p3)
{
break;
}
p1=p1->next;
}
return circleTru
4000
e;
}
else
{
while (head1->next!=NULL)
{
head1=head1->next;
}
while (head2->next!=NULL)
{
head2=head2->next;
}
if (head1==head2)
{
return true;
}
else
{
return false;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表