【C++】无头单链表面试题(3)

题目:判断判断链表是否相交,若相交返回交点(假设链表可能带环)

分析:根据题目画图,由题目可分解3中情况:

           1.带环相交,交点不在环上

           2.带环相交,交点在环上

           3.不相交

     

设计函数:1.先判断两条链表是否相交

                  2.若相交,找出交点并把交点返回;

                     若不相交,返回NULL,结束函数。

                  3.找交点(可以分装一个函数):

                (1)创建四个Node指针,L1指向链表1的头,L2指向链表2的头,pos1指向链表1的环入口点,pos2指向链表2的环入口点;

                (2)如果在环外相交:将pos2->next=L2;然后调用判环函数IsCircle; 创建一个Node指针C接收C=IsCircle(p1);最后返回C。

                (3)如果不在环外相交则就是再环上相交,返回环上的一个结点位置就好。


程序代码:


Node*JudgeCrossCircle(Node*list1,Node*list2)      //14.判断判断链表是否相交,若相交返回交点(假设链表可能带环)
{
	if (list1 == NULL)
		return NULL;
	if (list2 == NULL)
		return NULL;
	Node*Cross(Node*p1,Node*p2,Node*plist1,Node*plist2);        //函数声明,下面求交点要用
	Node*p1 = list1;
	Node*p2 = list2;
	Node*plist1 = IsCircle(list1);    //若list1带环,plist1是其入口点
	Node*plist2 = IsCircle(list2);    //若list2带环,plist2是其入口点
	Node*temp = plist1;
	while (plist1!=temp->next)
	{
		if (temp == plist2)       //链表list1与链表list2相交
		{
			Node*Meet = Cross(p1,p2,plist1,plist2);           //求相遇点位置
				return Meet;
		}
		temp = temp->next;
	}
	if (plist1 == plist2)     //链表list1与链表list2相交
	{
		Node*Meet = Cross(p1,p2,plist1,plist2);           //求相遇点位置
		return Meet;
	}
	return NULL;
}
Node*Cross(Node*p1, Node*p2,Node*plist1,Node*plist2)     //求相遇点位置
{
	Node*L1 = p1;     //链表1的头
	Node*L2 = p2;     //链表2的头
	Node*pos1 = plist1;  //链表1的环入口点
	Node*pos2 = plist2;  //链表2的环入口点
	Node*C = NULL;
	if (pos1 ==pos2)           //在环外相交
	{
		plist2->next =p2;                   //将p2的尾结点与头结点相接
		C = IsCircle(p1);
		return C;
	}
	else            //在环上相交
	{
		C = plist1->next;     //将环上的一个点当做其交点
		return C;
	}
}

测试

int main()
{
	Node*mylist1;
	Init(&mylist1);
	Pushback(&mylist1, 1);
	Pushback(&mylist1, 2);
	Pushback(&mylist1, 3);
	Pushback(&mylist1, 4);
	Pushback(&mylist1, 5);
	Pushback(&mylist1, 6);
	Pushback(&mylist1, 7);
	Pushback(&mylist1, 8);
	Node*ret = Find(mylist1, 8);
	ret->next = Find(mylist1, 5);

	Node*mylist2;
	Init(&mylist2);
	Pushback(&mylist2, 0);
	Pushback(&mylist2, 11);
	Pushback(&mylist2, 12);
	Pushback(&mylist2, 13);
	Node*temp = Find(mylist2, 13);
	temp->next = Find(mylist1, 6);    //换Find的的第二个参数,可测试三种情况

	Node*Cross = JudgeCrossCircle(mylist1, mylist2);
	/*cout << Cross->data << endl;*/       //当不相交的时候,屏蔽该行

	system("pause");
	return 0;
}
(1)环外相交



(2)换上相交



(3)不相交











  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值