1.判断单链表是否带环?若带环,求环的长度?求环的入口点?
2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
1.判断单链表是否带环?若带环,求环的长度?求环的入口点?
判断链表是否带环:
//检查链表是否带环
//快慢指针
void Check_Ring(ListNode* pList)
{
//1链表为空
//2链表不为空
ListNode* slow = pList;
ListNode* fast = pList;
if(pList == NULL)
{
printf("此链表不带环\n");
return ;
}
else
{
while(fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow->next == fast->next)
{
printf("此链表带环\n");
return ;
}
}
printf("链表不带环\n");
}
}
求环长度:
//求一个带环链表环的长度
void Length_Of_Ring(ListNode* pList)
{
ListNode* fast = pList->next->next;
ListNode* slow = pList;
ListNode* pos;
int count=0;
assert(pList);
while(slow != fast)
{
slow = slow->next;
fast = fast->next->next;
}
if(fast == slow)
{
pos = slow;
slow = slow->next;
while(slow!=pos)
{
count++;
slow = slow->next;
}
count++;
printf("环的长度为:%d \n",count);
}
}
求带环链表的环入口点
//求一个环形链表的入环点
ListNode* Pos_to_Enter_ring(ListNode* pList)
{
ListNode* fast = pList->next->next;
ListNode* slow = pList;
ListNode* curPlist = pList;
ListNode* newhead;
ListNode* curnewhead;
assert(pList);
//找到交点
while(slow != fast)
{
slow =slow->next;
fast = fast->next->next;
}
//断开交点
newhead = slow->next;
curnewhead = newhead;
slow->next = NULL;
//找两条链的交点
while(curPlist!= NULL)
{
while(curPlist != curnewhead && curnewhead != NULL)
{
curnewhead=curnewhead->next;
}
if(curnewhead == curPlist)
{
return curnewhead;
}
curPlist=curPlist->next;
curnewhead=newhead;
}
}
2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
//判断两条不带环链表是否相交
void juge_no_ring_list_intersect(ListNode* pList1,ListNode* pList2)
{
//
ListNode* curpList1 = pList1;
ListNode* curpList2 = pList2;
assert(pList1&&pList2);
//判断尾节点是否相同即可
while(curpList1->next)
{
curpList1 = curpList1->next;
}
while(curpList2->next)
{
curpList2=curpList2->next;
}
if(curpList1 == curpList2)
{
printf("这两条链表相交\n");
}
else
{
printf("这两条链表不相交\n");
}
}
//求交点的思想和求环入口点的方法一样,在第二条链表里面找第一条链表的第一个公共点就行
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
1首先利用快慢指针和一些其他方法判断情况两条链表的基本情况。
2在情况分类清楚以后再对各种情况进行针对性的相交甄别
//考虑两条链表带环或者不带环
void juge_list_intersect(ListNode* pList1,ListNode* pList2)
{
//一:两条链表不带环
// 1相交 2不想交
//二:一条链表带环,另一条链表不带环
// 1不相交
//三:两条链表都带环
// 1相交 2不相交
ListNode* curpList1 = pList1;
ListNode* curpList2 = pList2;
ListNode* slow1 = pList1 ;
ListNode* fast1 = pList1;
ListNode* slow2 = pList2;
ListNode* fast2 = pList2;
int flag1 = 0; //等于1 链表带环 等于0 链表不带环
int flag2 = 0;
assert(pList1&&pList2);
//进行情况判断
while(fast1 && fast1->next)
{
slow1 = slow1->next;
fast1 = fast1->next->next;
if(slow1 == fast1)
{
flag1 = 1;
break;
}
}
while(fast2 && fast2->next)
{
slow2 =slow2->next;
fast2 =fast2->next->next;
if(slow2 == fast2)
{
flag2 = 1;
break;
}
}
//都不带环
if(flag1 == 0 && flag2 == 0)
{
printf("这是两条不带还的链表\n");
juge_no_ring_list_intersect(curpList1,curpList2);
}
//其中一个为带环 另外一个不带环
else if((flag1 == 1 && flag2 == 0) ||(flag2 == 1 && flag1 == 0))
{
printf("这两条链表的其中一条链表带环 这两条链表不相交\n");
}
else//两个都带环
{
//找到其中一个环的入口点
ListNode* enterpos = Pos_to_Enter_ring(pList1);
fast2 = pList2;
slow2 = pList2;
while(fast2 && fast2->next)
{
slow2 = slow2->next;
fast2 = fast2->next->next;
if(enterpos == slow2)
{
printf("这两条带环链表 相交\n");
break;
}
if(slow2 == fast2)
{
printf("这两条带环链表不相交\n");
break;
}
}
}
}
//判断交点的思想上面也已经提过就不再写了
关于链表的问题思想最重要,当了解了思想以后,写代码就容易很多。