C语言实现单链表面试题--进阶

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

ListNode* judge_band(ListNode *pList)//判断单链表是否带环?若带环,求环的入口点?
{
	ListNode *fast = pList;
	ListNode *slow = pList;

	while((fast->next != NULL) && (fast->next->next != NULL))
	{
		fast = fast->next->next;
		slow = slow->next;
		if(fast == slow)
			break;
	}
	if((fast->next == NULL) || (fast->next->next == NULL))
		return NULL;

	fast = pList;
	while(fast != slow)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return fast;
}

判断单链表是否带环?若带环,求环的长度

int judge_band_length(ListNode *pList)//求环的长度
{
	int count = 0;
	ListNode* tmp = judge_band(pList);
	assert(pList);

	if(tmp == NULL)
	{
		return 0;
	}
	else
	{
		ListNode* step = tmp->next;
		while(step != tmp)
		{
			count++;
			step = step->next;
		}
		count++;//环的入口点要加在环长里
	}
	return count;
}

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

ListNode* judge_intersect(ListNode *pList1, ListNode *pList2)//判断两个链表是否相交,若相交,求交点。(假设链表不带环)
{
	ListNode *p1 = pList1;
	ListNode *p2 = pList2;
	assert(pList1 && pList2);

	while(p1->next)
		p1 = p1->next;
	while(p2->next)
		p2 = p2->next;

	if(p1 != p2)
		return NULL;
	else
	{
		int len1 = 0, len2 = 0;
		p1 = pList1,p2 = pList2;

		while(p1)
		{
			len1++;
			p1 = p1->next;
		}
		while(p2)
		{
			len2++;
			p2 = p2->next;
		}

		if(len1 > len2)
		{
			int tmp = len1 - len2;
			p1 = pList1;
			while(tmp--)
			{
				p1 = p1->next;
			}
			p2 = pList2;
		}
		else
		{
			int tmp = len2 - len1;
			p2 = pList2;
			while(tmp--)
			{
				p2 = p2->next;
			}
			p1 = pList1;
		}

		while(p1 != p2)
		{
			p1 = p1->next;
			p2 = p2->next;
		}
		return p1;
	}
}

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


ListNode* judge_band_intersect(ListNode *pList1, ListNode *pList2)//判断两个链表是否相交(假设链表可能带环)
{
	ListNode *p1_entrance = judge_band(pList1);
	ListNode *p2_entrance = judge_band(pList2);
	
	if((p1_entrance == NULL) && (p2_entrance == NULL))//都不带环
	{
		return judge_intersect(pList1, pList2);
	}
	else if((p1_entrance == NULL) || (p2_entrance == NULL))//一个带环一个不带环
	{
		return NULL;
	}
	else//两个都带环
	{
		ListNode *p1 = pList1;
		ListNode *p2 = pList2;

		if(p1_entrance == p2_entrance)//都带环且入口点相等求交点
		{
			int len1 = 0, len2 = 0;
			int tmp = 0;

			while(p1 != p1_entrance)
			{
				len1++;
				p1 = p1->next;
			}
			while(p2 != p2_entrance)
			{
				len2++;
				p2 = p2->next;
			}

			if(len1 >len2)
			{
				int tmp = len1 - len2;
				p1 = pList1;
				while(tmp--)
				{
					p1 = p1->next;
				}
				p2 = pList2;
			}
			else
			{
				int tmp = len2 - len1;
				p2 = pList2;
				while(tmp--)
				{
					p2 = p2->next;
				}
				p1 = pList1;
			}
			while(p1 != p2)
			{
				p1 = p1->next;
				p2 = p2->next;
			}
			return p1;
		}
		else//都带环且入口点不相等,判断是否相交
		{
			p1 = p1_entrance;
			p2 = p2_entrance;
			while(p1->next != p1_entrance)
			{
				p1 = p1->next;
				if(p1 == p2_entrance)
					return p1_entrance;//有两个交点,返回p1_entrance或p2_entrance都可以
			}
			return NULL;
		}
	}
}

复杂链表的复制,返回新链表的头节点

typedef struct ComplexNode //复杂链表的结构体
{ 
	int _data ; // 数据 
	struct ComplexNode * next; // 指向下一个节点的指针 
	struct ComplexNode * random; // 指向随机节点(可以是链表中的任意节点 or 空) 
}ComplexNode;
ComplexNode* cpye_dif_List(ComplexNode *pList)//复杂链表的复制,返回新链表的头节点
{
	ComplexNode *NewList = NULL;
	ComplexNode *tmp = pList;
	assert(pList);

	while(tmp->next)
	{
		Insert_Nohead(tmp->next, tmp->data);
		tmp = tmp->next->next;
	}
	tmp->next = CreatNode(tmp->data);

	NewList = pList->next;
	tmp = NewList;
	while(pList != NULL)
	{
		tmp->random = pList->random;
		pList->next = tmp->next;
		pList = pList->next;
		if(!pList)
			tmp->next = NULL;
		else
		{
			tmp->next = pList->next;
			tmp = tmp->next;
		}
	}
	return NewList;
}
测试用例可在http://blog.csdn.net/qq_35452533/article/details/73130218查看

代码是测试过得,如有不对之处,欢迎留言指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值