求两个链表是否相交,若相交,求交点(链表可能带环)

来源:互联网 发布:和风天气json解析封装 编辑:程序博客网 时间:2024/05/29 04:30

解题思路:1.判断两个链表是否带环,若两个链表一个带环一个不带环,不可能相交

                    2.若俩个链表都不带环,判断交点,前文已有

                    3.若俩个链表都带环,则有俩种情况,一种在环外相交,一种是在环内相交。需要分情况判断


Data LoopList(List* phead)
{
assert(phead);
List* fast = phead;
List* slow = phead;
if (phead->next == NULL)
{
printf("不带环\n");
return -1;
}
while (1)
{
slow = slow->next;
fast = fast->next->next;
if ((fast == NULL) || (fast->next == NULL))
{
printf("不带环\n");
return -1;


}
else if (fast == slow)
{
printf("带环\n");
return 1;


}
}
return 0;
}


void crossList(List* phead_1, List* phead_2)
{
assert(phead_1);
assert(phead_2);
List* phead_1_1 = phead_1;
List* phead_2_2 = phead_2;
int count_1 = 0;
int count_2 = 0;
int dif = 0;
while (phead_1_1)
{
phead_1_1 = phead_1_1->next;
count_1++;
}
while (phead_2_2)
{
phead_2_2 = phead_2_2->next;
count_2++;
}
phead_1_1 = phead_1;
    phead_2_2 = phead_2;
if (count_1 < count_2)
{
dif = count_2 - count_1;
while (dif>0)
{
phead_2_2 = phead_2_2->next;
dif--;
}
}
if (count_1 > count_2)
{
dif = count_1 - count_2;
while (dif > 0)
{
phead_1_1 = phead_1_1->next;
dif--;
}
}
while (phead_1_1 != NULL&&phead_2_2 != NULL)
{
if (phead_1_1 == phead_2_2)
{
printf("有交点,交点处的数据为:%d \n", phead_1_1->arrary);
break;
}
phead_1_1 = phead_1_1->next;
phead_2_2 = phead_2_2->next;
}
}


void crosslist_H(List* phead1,List* phead2)
{
assert(phead1);
assert(phead2);
if ((LoopList(phead1) == -1) && (LoopList(phead2) == -1))
{
crossList(phead1, phead2);                                   //都不带环
return;
}
else if (((LoopList(phead1) == 1) && (LoopList(phead2) == -1)) || ((LoopList(phead1) == -1) && (LoopList(phead2) == 1)))
{
printf("不相交\n");                                                       //一个带环一个不带环肯定不相交
return;
}
else
{
//求phead1环的入口点
List* fast = phead1;
List* slow = phead1;
while (1)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
break;
}
}
slow = phead1;
while (slow != fast)
{
slow = slow->next;
fast = fast->next;
}
List* pphead1 = fast;    //环phead1的入口点
//求phead2的入口点
fast = phead2;
slow = phead2;
while (1)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
break;
}
}
slow = phead2;
while (slow != fast)
{
slow = slow->next;
fast = fast->next;
}
List* pphead2 = fast;                                //环phead2的入口点
List* Node1 = pphead1;                          //记录phead1环的入口点
List* Node2 = pphead2;                          //记录phead2环的入口点
//1.判断是否在环外相交
fast = phead1;                                            //让fast指向phead1的起始位置
slow = phead2;                                          //让slow指向phead2的起始位置
int a = 0;                                                      //用来记录俩单链表在入口前长度的差值
int len1 = 0;                                                //phead1入环前链的长度
int len2 = 0;                                                //phead2入环前链的长度
while (fast != pphead1)
{
len1++;
fast = fast->next;
}
while (slow != pphead2)
{
len2++;
slow = slow->next;
}
fast = phead1;
slow = phead2;
if (len1 > len2)
{
a = len1 - len2;
while (a > 0)
{
fast = fast->next;
a--;
}
}
else
{
a = len2 - len1;
while (a > 0)
{
slow = slow->next;
a--;
}
}
int b = 0;
while (fast != pphead1)
{
if (fast == slow)
{
b = 1;
break;
}
fast = fast->next;
slow = slow->next;
}
if (b == 1)
{
printf("在环外相交,交点处的数据为:%d \n", fast->arrary);
return;
}
//判断是否在环内相交
Node1 = Node1->next;
if (pphead1 == pphead2)
{
printf("在环内相交,交点处的数据为:%d \n", pphead1->arrary);
return;
}
while (Node1 != pphead1)
{
if (Node1 == pphead2)
{
printf("在环内相交,交点处的数据为:%d 或 %d\n", pphead1->arrary, pphead2->arrary);
return;
}
Node1 = Node1->next;
}
}
阅读全文
0 0
原创粉丝点击