链表面试题:判断两个链表是否相交

来源:互联网 发布:阿里云盘怎么用 编辑:程序博客网 时间:2024/06/07 14:14

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

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

采用对齐的思想。计算两个链表的长度 L1 , L2,分别用两个指针 p1 , p2 指向两个链表的头,然后将较长链表的 p1(假设为 p1)向后移动L2 - L1个节点,然后再同时向后移动p1 , p2,直到 p1 = p2。相遇的点就是相交的第一个节点。

pNode CheckCircle(pList plist)//判断链表是否有环{     assert(plist);     pNode fast = plist;     pNode slow = plist;     if (fast && fast->next)     {          fast = fast->next->next;          slow = slow->next;          if (fast == slow)          {              return slow;          }     }     return NULL;}int CircleLength(pList plist)//求环的长度{     assert(plist);     pNode tmp = CheckCircle(plist);     pNode cur = CheckCircle(plist);     int count = 0;     do{          count++;          cur = cur->next;     } while (cur == tmp);     return count;}pNode FindNode(pList plist)//碰撞点//碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。{     pNode tmp = CheckCircle(plist);     pNode cur = pHead;     while (tmp != cur)     {          cur = cur->next;          tmp = tmp->next;     }     return tmp;}int CircleListLength(pList plist)//求环的长度{     pNode cur = pHead;     pNode tmp = FindNode(plist);     int count = 0;     while (tmp != cur)     {          ++count;          cur = cur->next;     }     return count + CircleLength(plist);}bool CheckNoCircleCross(pList plist1, pList plist2)//判断两个链表是否相交{//判断两个链表的最后一个节点是否相同,如果相同,则相交     assert(plist1);     assert(plist2);     while (plist1->next)     {          plist1 = plist1->next;     }     while (plist2->next)     {          plist2 = plist2->next;     }     if (plist1 == plist2)     {          return true;     }     else          return false;}int ListLength(pList plist){     int count = 0;     while (plist)     {          ++count;          plist = plist->next;     }     return count;}pNode FindNoCircleIntersectNode(pList plist1, pList plist2)//查找相交节点{     int l1 = ListLength(plist1);     int l2 = ListLength(plist2);     if (l1 > l2)     {          for (int i = 0; i < l1 - l2; ++i)          {              plist1 = plist1->next;          }     }     else     {          for (int i = 0; i < l2 - l1; ++i)          {              plist2 = plist2->next;          }     }     while (plist1 != NULL)     {          if (plist1 == plist2)          {              return plist1;          }          plist1 = plist1->next;          plist2 = plist2->next;     }     return NULL;}pNode FindIntersectNode(pList plist1, pList plist2)// 查找交点(不知是否有环){     if ((!CheckCircle(plist1))&&(!CheckCircle(plist2)))     {          FindNoCircleIntersectNode(plist1, plist2);     }     if (CheckCircle(plist1) && (!CheckCircle(plist2)))     {          return NULL;     }     if (CheckCircle(plist2) && (!CheckCircle(plist1)))     {          return NULL;     }     int l1 = CircleListLength(plist1);     int l2 = CircleListLength(plist2);     if (l1 > l2)     {          for (int i = 0; i < l1 - l2; ++i)          {              plist1 = plist1->next;          }     }     if (l1 < l2)     {          for (int i = 0; i < l2 - l1; ++i)          {              plist2 = plist2->next;          }     }     while (plist1)     {          if (plist1 == plist2)          {              return plist1;          }          plist1 = plist1->next;          plist2 = plist2->next;     }}
原创粉丝点击