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

本文探讨了链表相交的三种主要情形:两链表皆有环、一链表有环另一无环及两链表均无环,并提供了详细的算法实现及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题思路:链表相交有3种大的情况,两个链表都带环;都没带环;一个带环,一个没带环;

1.两个链表都带环。


2.一个链表带环,一个链表没有带环,则他们肯定不相交。


3.两个链表都没带环。


代码:

 //判断链表是否带环
 Node* ListIsLoop(Node* head)
 {
	 Node* solw=head;
	 Node* fast=head;
	 while(fast&&fast->next) //奇数个fast->next,偶数个fast
	 {
		 solw=solw->next;
		 fast=fast->next->next;
		 if(solw==fast)
			 return solw; //带环
	 }
	 return NULL; //没带环
 }
 //判断两个链表是否相交,若相交,求交点
 Node* ListIsIntersect(Node* head1,Node* head2)
 {
	 if(head1==NULL||head2==NULL) //有一个链表为空
		 return NULL;
	 Node* p1=ListIsLoop(head1);  //判断链表1是否带环
	 Node* p2=ListIsLoop(head2);  //判断链表2是否带环
	 if(p1!=NULL&&p2!=NULL)  //两个链表都带环
	 {
		 Node* cur=p2;
		 while(cur!=p1)
		 {
			 cur=cur->next;
			 if(cur==p2) //cur走了一圈了,还没有与p1相遇,说明他们不相交
			 {
				 return NULL;
			 }
		 }
		 //说明两个链表相交
		 //带环相交有两种情况,交点在环上,交点没在环上
		 Node* start1=LoopStart(head1);
		 Node* start2=LoopStart(head2); //求环的入口点
		 if(start1==start2)  //两个链表的入口点一样,说明交点在链表上,没在环上
		 {
			 //求交点可以等价于求两个无环链表的交点
			 Node* cur1=head1;
			 Node* cur2=head2;
			 while(cur1!=cur2)
			 {
				 if(cur1==start1)
					 cur1=head2;
				 else
				 {
					 cur1=cur1->next;
				 }
				 if(cur2==start2)
					cur2=head1;
				 else
				 {
					cur2=cur2->next;
				 }
			 }
			 return cur1;

		 }
		 else  //交点在环上,两个入口点都可能是交点,随便返回一个
		 {
			 return start2;
		 }

	 }
	 else if(p1==NULL&&p2==NULL)  //两个链表都没带环
	 {
		 Node* cur1=head1;
		 Node* cur2=head2;
		 while(cur1!=cur2)
		 {
			 if(cur1==NULL)
				 cur1=head2;
			 else
			 {
				 cur1=cur1->next;
			 }
			 if(cur2==NULL)
				cur2=head1;
			 else
			 {
				cur2=cur2->next;
			 }
		 }
		 return cur1;
	 }
	 else  //一个链表带环,一个没有带环,他们肯定没有交点
	 {
		 return NULL;
	 }
 }
 void fun6()
 {
	 Node* node1=new Node(2);
	 Node* node2=new Node(8);
	 Node* node3=new Node(6);
	 Node* node4=new Node(9);
	 Node* node5=new Node(5);
	 node1->next=node2;
	 node2->next=node3;
	 node3->next=node3;

	 node4->next=node5;
	 node5->next=node3;
	 Node* node=ListIsIntersect(node1,node4);  
	 if(node!=NULL)
		cout<<node->data<<endl;
	 else
		 cout<<"0"<<endl;
 }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值