单链表常见面试题(二)

1.判断单链表是否带环?若带环,求环的长度?求环的入口点?


(1)判断是否带环

Node* IfRing(Node* list)
{
	Node* slow = list;
	Node* fast = list;
	while (fast&&fast->next)      
	{
		slow = slow->next;   //慢指针一次走一步
		fast = fast->next->next;//快指针一次走两步
		if (slow==fast)
		{
			return fast;   //fast追上slow时返回快指针
		}
	}
	return NULL;  //表示fast->next为空,链表不带环
}
(2)求环的长度

求环的长度只需在第一次的相遇点开始,快慢指针继续走,当再次相遇时,走过的次数即使长度

int Length(Node* list)
{
	Node* fast = IfRing(list);
	if (fast)
	{
		Node* slow = fast;
		int count = 0;
		while (fast&&fast->next)
		{
			slow = slow->next;
			fast = fast->next->next;
			++count;
			if (slow == fast)
			{
				return count;
			}		
		}
		return 0;
	}
}
(3)求环的入口



Node* Entry(Node* list)
{
	Node* fast = IfRing(list);//fast代表交点开始走
	Node* cur = list;//cur从最开始的结点走
	while (fast&&fast->next)
	{
		cur = cur->next;
		fast = fast->next;
		if (fast == cur)  //相遇时代表走到了入口点
		{
			return fast;
		}
	}
	return NULL;
}

2.判断两个链表是否相交,若相交,求交点。(假设链表不带环) 


求两个链表的相交点:


代码

ListNode* IfCoverge(ListNode** list1, ListNode** list2)//返回值是环内相遇点 判断是否相交(链表不带环)
{
       //让一个链表的尾指向另外一个链表的头,若有交点,则会形成环
	if (*list1 == NULL)
		return NULL;
	if (*list2 == NULL)
		return NULL;
	ListNode* cur1 = *list1;
	ListNode* cur2 = *list2;
	while (cur1->_next)
	{
		cur1 = cur1->_next;
	}
	while (cur2->_next)
	{
		cur2 = cur2->_next;
	}
	if (*list1 == *list2)
		return *list1;
	else if (cur1 == cur2)
		return cur1;
	else
	{
		cur2->_next = *list1;
		IfRing(*list2);  //调用之前的判断是否带环的函数。返回值值快慢指针的相遇的点
	}
}


ListNode* Coverge(ListNode* list1,ListNode* list2)//两个链表交点(可能也是环入口点)
{                              //已知两个链表相交,则长的链表先走K步,K(size1-size2).之后两个链表同时走,相遇点就是交点
	ListNode* cur1 = list1;
	ListNode* cur2 = list2;
	size_t size1 = Size(list1);
	size_t size2 = Size(list2);
	if (size1 > size2)
	{
		size_t k = size1 - size2;
		while (k--)
		{
			cur1 = cur1->_next;
		}

	}
	else
	{
		size_t k = size2 - size1;
		while (k--)
		{
			cur2 = cur2->_next;
		}
	}
	while (1)
	{
		if (cur1==cur2)
			return cur1;
		cur1 = cur1->_next;
		cur2 = cur2->_next;
	}
}

3 判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】 



1 两个链表都不带环

(1)没有交点  (2)有一个交点


2 一个链表带环,一个不带环

 (3)没有交点


3 两个链表都带环

 (4)没有交点   (5)有一个交点(交点有可能是入口点)    (6)有两个交点

ListNode* Node(ListNode* list1, ListNode* list2)
{
	ListNode* ret1 = Ret(list1);
	ListNode* ret2 = Ret(list2);
	if (!ret1&&!ret2)    //1 -两个链表都不带环
	{
		ListNode* point = IfCoverge(&list1, &list2);
		if (point == NULL)
		{
			return NULL;    //1-1 没有交点
		}

		return Coverge(list1, list2); //1-2 一个交点  
	}
	else if ((!ret1&&ret2) || (ret1&&!ret2))  //2 一个带环一个不带环
	{
		return NULL;
	}
	else               // 3 两个都带环 
	{
		//1-两个环不相交
		//2-两个环的入口点相同
		//3-两个环相交且有两个交点
		if (ret1 == ret2)  //  3--2  入口点相同
		{
			ret1->_next = NULL;
			ret2->_next = NULL;
			Coverge(list1, list2);
		}
		else
		{
			ListNode* tmp = ret1->_next;
			while (tmp != ret1&&tmp != ret2)
			{
				tmp = tmp->_next;
			}
			if (tmp == ret1)
			{
				printf("两个链表分别带环,但不相交\n");
				return NULL;      //3-1 没有交点
			}
			printf("有两个交点\n");      //3-3 有两个交点
			printf(" %d\n", ret1->_data);
			return ret2;
		}
	}
}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值