链表相交

本文详细介绍了如何判断两个链表是否相交,包括链表无环、单链表带环和双链表带环三种情况,并提供了具体的实现代码。
判断两个链表是否相交???

我们先来分析一下两个链表的相交问题,如图:

两条链表都不带环:




一条链表带环,一条不带环:



两条链表都带环:



//如果两个链表都不带环
int NotCycleCheckCross(pLinkNode head1,pLinkNode head2)
{
	pLinkNode list1 = head1->next;
	pLinkNode list2 = head2->next;
	if ((NULL==list1 )||(NULL==list2))
	{
		return 0;      //不相交
	}
	while (NULL != list1->next)
	{
		list1 = list1->next;
	}
	while (NULL != list2->next)
	{
		list2 = list2->next;
	}
	if (list1==list2)
	{
		return 1;      //相交
	}
	return 0;          //不相交
}

//链表带环,判断两个链表是否相交
int CycleCheckCross(pLinkNode meet1, pLinkNode meet2)
{
	pLinkNode cur = meet1->next;
	if (meet1 == meet2)
	{
		return 1;     //链表相交
	}
	while ((cur != meet1)&&(cur!=meet2))
	{
		cur = cur->next;
	}
	if (cur == meet2)
	{
		return 1;   //链表相交
	}
	return 0;       //不相交
}


//将上面两个函数封装成一个函数
int CheckCross(pLinkNode head1, pLinkNode head2)          //参数为两个头结点
{
	pLinkNode fast = NULL;
	pLinkNode slow = NULL;
	pLinkNode meet1 = NULL;
	pLinkNode meet2 = NULL;
	if (head1->next == NULL || head2->next == NULL)
	{
		return 0;          //至少一个链表为空链表,则两个链表一定不相交
	}
	fast = head1->next;
	slow = head1->next;
	while (fast&&fast->next)           //判断链表head1是否带环
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
		{
			meet1 = fast;
			break;
		}
	}
	fast = head2->next;
	slow = head2->next;
	while (fast&&fast->next)           //判断链表head2是否带环
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
		{
			meet2 = fast;
			break;
		}
	}
	if ((meet1 == NULL) && (meet2 == NULL))       //如果两个链表都不带环
	{
		return NotCycleCheckCross(head1, head2);
	}
	else if (meet1&&meet2)                        //如果两个链表都带环
	{
		return CycleCheckCross(meet1, meet2);
	}
	//如果两个链表一个带环一个不带环,则一定不相交直接返回0
	return 0;            //不相交
}




链表相交点的求解方法有以下几种: - **利用“两指针遍历总长度相等”消除长度差**:设链表A长度为m,链表B长度为n,指针1从A出发、指针2从B出发,遍历完当前链表后立即切换到另一链表头部,最终两指针会走m + n步。若有点则在点相遇,无点则同时为null [^1]。 - **差值步法**:先定义两个指针nodeA、nodeB,分别指向两条链表的头节点,再一人一步往后走,如果这两条链表相交,则两个指针必定会相遇,若没有相遇则返回null,说明两条链表没有相交 [^2]。 - **双循环对比法**:时间复杂度O(n^2),空间复杂度O(1)。链表A中的节点依次与链表B中的每个节点比较,若出现节点相同,则相交且为第一个点;若链表A走到空依然没有相同的节点,则不相交 [^5]。 ### 示例代码 ```python # 利用“两指针遍历总长度相等”消除长度差的示例代码 class ListNode: def __init__(self, x): self.val = x self.next = None def getIntersectionNode(headA, headB): pA, pB = headA, headB while pA != pB: pA = pA.next if pA else headB pB = pB.next if pB else headA return pA # 差值步法示例代码 def getIntersectionNode2(headA, headB): nodeA, nodeB = headA, headB while nodeA != nodeB: nodeA = nodeA.next if nodeA else None nodeB = nodeB.next if nodeB else None if nodeA is None and nodeB is None: break return nodeA # 双循环对比法示例代码 def getIntersectionNode3(headA, headB): curA = headA while curA: curB = headB while curB: if curA == curB: return curA curB = curB.next curA = curA.next return None ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值