链表的交点问题


单链表交点问题的分类:

a.两个链表都无环 

b.两个链表都有环(交点在环外;交点在环内)

下边给出图示:


                    

注意:两个链表的交点处,并不仅仅是data域相等,还要有next域相同。

如果一个链表有环,另一个链表无环,他们是不可能有交点的。

反证:如果有交点,一个链表有环,另一个链表必然有环。不符合条件。

从以上可以看出,要想完全弄清楚这个交点问题,必须要判断,链表是否有环;链表的交

点。(关于链表是否有环,以及环的入口问题,在前边的文章中已有整理)

下边给出代码:

typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
	LinkNode *pHead;
}LinkList,*pLinkList;
pLinkNode CrossNoCircleNode(pLinkList plist1, pLinkList plist2)//两链表都无环
{
	int len1 = 0;
	int len2 = 0;
	pLinkNode cur1 = plist1->pHead;
	pLinkNode cur2 = plist2->pHead;
	while (cur1)
	{
		len1++;
		cur1 = cur1->next;
	}
	while (cur2)
	{
		len2++;
		cur2 = cur2->next;
	}
	cur1 = plist1->pHead;
	cur2 = plist2->pHead;
	int d = len1 - len2;
	if (d >= 0)
	{
		while (d--)
		{
			cur1 = cur1->next;
		}
	}
	else
	{
		d = -d;
		while (d--)
		{
			cur2 = cur2->next;
		}
	}
	while (cur1 != cur2 &&cur1 && cur2)
	{
		cur1 = cur1->next;
		cur2 = cur2->next;
	}
	if (cur1 != NULL && cur2 != NULL)
	{
		return cur1;
	}
	return NULL;
}

pLinkNode CrossCircleNode(pLinkList plist1, pLinkList plist2)//两链表有环
{
	pLinkNode cur1 = plist1->pHead;
	pLinkNode cur2 = plist2->pHead;
	pLinkNode frontCrossNode1 = NULL;
	pLinkNode frontCrossNode2 = NULL;
	pLinkNode CrossNode = NULL;

	//求出两个环的入口
	frontCrossNode1 = firstCrossNode(plist1);
	frontCrossNode2 = firstCrossNode(plist1);

	if (frontCrossNode1->next == frontCrossNode2->next)//两环入口相同的情况
	{
		 frontCrossNode2->next = cur2;
		 CrossNode = firstCrossNode(plist1);
		 return CrossNode;
	}
	else
	{
		while (cur2->next != frontCrossNode2)
		{
			if (frontCrossNode1 == cur2)
			{
				return frontCrossNode1;
			}
			cur2 = cur2->next;
		}
		return NULL;
	}
}

pLinkNode CrossNode(pLinkList  plist1, pLinkList plist2)
{
	assert(plist1 && plist2);
	pLinkNode ret = NULL;
	if (plist1->pHead == NULL || plist2->pHead == NULL)
	{
		return NULL;
	}
	if (isCircle(plist1) == NULL && isCircle(plist2) == NULL)//两个链表都无环
	{
		//调用无环链表交点的函数
		ret = CrossNoCircleNode(plist1,plist2);
		return ret;
	}
	if (isCircle(plist1) && isCircle(plist2))//两个链表都带环
	{
		ret = CrossCircleNode(plist1,plist2);
		return ret;
	}
	else
	{
		return NULL;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值