单链表是否相交的问题

单链表相交分为三种情况。

  • 两个链表相交且都不带环

//单链表相交1
Node* IsCross_NoCycle(List list1, List list2)
{
	assert(list1 && list2);
	int len1 = length(list1);
	int len2 = length(list2);
	Node* longlist;
	Node* shortlist;
	int gap = 0;
	if (len1 > len2)
	{
		longlist = list1;
		shortlist = list2;
		gap = len1 - len2;
	}
	else
	{
		longlist = list2;
		shortlist = list1;
		gap = len2 - len1;
	}

	while (gap--)
	{
		longlist = longlist->next;
	}

	//一起走
	while (longlist != shortlist)
	{
		longlist = longlist->next;
		shortlist = shortlist->next;
	}
	if (longlist != shortlist)
	{
		return false;
	}
	else {
		return longlist;
	}
}

test

int main()
{
	Node head1;
	InitList(&head1);
	tailInsert(&head1, 1);
	tailInsert(&head1, 2);
	tailInsert(&head1, 3);
	Show(&head1);

	Node head2;
	InitList(&head2);
	tailInsert(&head2, 4);
	tailInsert(&head2, 5);
	tailInsert(&head2, 6);
	tailInsert(&head2, 111);
	tailInsert(&head2, 8);
	tailInsert(&head2, 9);
	Show(&head2);

	Node *cross = Find(&head2, 8);
	Node *tail = Find(&head1, 3);
	tail->next->next = cross;
	Show(&head1);

	printf("交点是:%d\n", IsCross_NoCycle(&head1, &head2)->data);
	return 0;
}
  • 当链表一个有环一个无环时

  • 当两个链表都有环时

Node* IsCross_Cycle(List list1, List list2)
{
	assert(list1 && list2);
	//求链表带环的相遇点
	Node* MeetNode1 = Circle(list1);//返回环的入口
	Node* MeetNode2 = Circle(list2);
	Node* entry1;
	Node* entry2;
	Node* meet, *cur1;

	//判断链表是否带环
	if (MeetNode1 == NULL || MeetNode2 == NULL)
		return NULL;//其中一个链表不带环,则不会相交,返回NULL

	//两个链表都带环,相交的两种情况
	//1.相同的入口点  2.不同的入口点
	entry1 = GetEntry(list1, MeetNode1);
	entry2 = GetEntry(list2, MeetNode2);
	if (entry1 == entry2)//相同的入口点,返回交点
	{
		//entry1->next = NULL;
		//entry2->next = NULL;
		meet = IsCross_NoCycle(list1, list2);
		return meet;
	}

	//不同的入口点的情况
	//判断条件:从MeetNode1开始遍历链表,如果找到和MeetNode2相等的节点,则证明共用环
    //如果相交,返回任意一个入口点
	cur1 = MeetNode1->next;
	while (cur1 != MeetNode1 && cur1 != MeetNode2)
	{
		cur1 = cur1->next;
	}
	if (cur1 == MeetNode2)
		return entry1;

	return NULL;//不相交
}

test 

int main()
{
	Node head1;
	InitList(&head1);
	tailInsert(&head1, 1);
	tailInsert(&head1, 2);
	tailInsert(&head1, 3);
	Show(&head1);

	Node head2;
	InitList(&head2);
	tailInsert(&head2, 4);
	tailInsert(&head2, 5);
	tailInsert(&head2, 6);
	tailInsert(&head2, 7);
	tailInsert(&head2, 8);
	tailInsert(&head2, 9);
	tailInsert(&head2, 10);
	tailInsert(&head2, 11);
	Show(&head2);

	Node *cross = Find(&head2, 8);
	Node *tail1 = Find(&head1, 3);
	tail1->next->next = cross;

	Node *tail2 = Find(&head2, 11);
	Node *entry = Find(&head2, 9);//入口点
	tail2->next->next = entry;//带环

	printf("交点是:%d\n", IsCross_Cycle(&head1, &head2)->data);
	return 0;
}
发布了35 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41078889/article/details/103250454