1. 程式人生 > >判斷連結串列相交,若相交,求交點。(假設連結串列可能帶環)

判斷連結串列相交,若相交,求交點。(假設連結串列可能帶環)

首先我們分析,兩個連結串列是否相交,是否帶環,有以下幾種情況:

在這裡插入圖片描述

求兩個連結串列是否帶環可以分成三個情況:
1.都不帶環,可以轉換成兩個連結串列是否相交的問題。
2.一個帶環,一個不帶環。–>不相交
3.都帶環:
   分別求環的入口點
    1.入口點相同–>一定相交在環外
    2.入口點不同
      分別求環的長度
      1.長度不相等–>兩個連結串列不相交
      2.長度相等
      一個在它的環入口點等著,另一個從他的環入口點出發,在長度內是否相遇,如果相遇–>相交在環內,不相遇–>不相交。
程式碼:

Node *CircleMeetNode(Node *list1, Node *list2) {  Node *m1=IsCircleList(list1);//若帶環,返回相遇點  Node *m2 = IsCircleList(list2);  Node *p1 = EnterNode(list1);//返回環的入口點  Node *p2 = EnterNode(list2);  Node *entryNext1 = p1->next;//儲存入口點的next,為恢復環做準備  Node *entryNext2 = p2->next;  Node *meet = NULL;  Node *cur = m1->next; 
 if (m1 == NULL && m2 == NULL)
 {//兩個都不帶環,轉換為兩個連結串列相交問題
  return Crossing(list1, list2);
 }
 else if (m1&&m2)//兩個都帶環,分三種情況
 {
  while (cur != m1 && cur != m2)//1.兩個不相交
  {
   cur = cur->next;
  }
  if (cur == m1)
  {
   return NULL;
  }
  else
  {
   if (p1 == p2)//2.入口點相等,相交在環外
   {
    p1->next = NULL;//斷開環轉化成Y型求交點問題
    p2->next = NULL;
    meet=Crossing(list1, list2);
    p1->next = entryNext1;//恢復環
    p2->next = entryNext2;
    return meet;
   }
   else//?
   {//3.入口點不相等
    return p2;
   }  }
 }
 else//一個帶環,一個不帶環
 {
  return NULL;
 }
}