标签:笔试 面试 c/c++ 单链表 判断两链表是否相交 求交点
判断两链表是否相交,求交点(假设链表不带环)
判断两链表是否相交,求交点(假设链表可能带环)
RingEntry_Point()等函数见前篇.
SListNode* Intersect(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表不带环) { //思路:若不带环,只有相交/不想交两种情况 // 与RingEntry_Point()函数方法相同: // 求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短链表头开始, // 两链表一起走,相遇点就为入口点 if (L != NULL&&M != NULL) { SListNode *cur = L; SListNode *NewNode = M; int c1 = _LengthNode(cur); int c2 = _LengthNode(NewNode); int minus = _LengthNode(cur) - _LengthNode(NewNode); if (minus > 0) { while (minus--) { cur = cur->next; } } else { int tmp = -minus; while (tmp--) { NewNode = NewNode->next; } } while (NewNode != cur&&NewNode != NULL&&cur != NULL) { NewNode = NewNode->next; cur = cur->next; } if (NewNode == NULL || cur == NULL) return NULL; return cur; } return NULL; } SListNode* IntersectRing(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表可能带环) { //思路:考虑全部情况:1、不带环 相交/不相交 2、带环 一条带环一条不带环/两条都带环(其中又分交点不在环上/交点在环上) // //区分是哪一种情况,分别实现 if (L != NULL&&M != NULL) { if (!IsRing(L) && !IsRing(M))//不带环 return Intersect(L, M); else if ((IsRing(L) && !IsRing(M)) || (!IsRing(L) && IsRing(M)))//一条带环一条不带环 return NULL; else { //先求两链表的环入口点,若入口点一样,则为第5种情况否则是第4、6种情况 SListNode *re1 = RingEntry(L); SListNode *re2 = RingEntry(M); if (re1 == re2)//第5种情况 化为不带环相交链表问题 { SListNode* m1 = IsRing(L); SListNode*recover = m1->next;// 复原仿照RingEntry_Point()函数 m1->next = NULL; SListNode*cur = Intersect(L, M); m1->next = recover; return cur; } else//第4、6种情况若其中一个环入口点在另一个环上,则为第6种情况,否则为第4种情况 { SListNode *tmp = re1->next; while (tmp != re1&&tmp != re2) tmp = tmp->next; if (tmp == re1)//第4种情况 return NULL; printf("两链表带环,并且有两个交点\n");//第6种情况 SListNode *tmp1 = re1->next; re1->next = NULL; PrintNode(re1); re1->next = tmp1; return re2; } } } else return NULL; }
测试
void Test10() { printf("//Test10() Intersect() \n"); SListNode *LL = NULL; PushBack(LL, 1); PushBack(LL, 2); PushBack(LL, 3); PushBack(LL, 4); PushBack(LL, 5); PrintNode(LL); SListNode *MM = NULL; PushBack(MM, 1); PushBack(MM, 2); MM->next->next = LL->next->next->next; PrintNode(MM); SListNode *NN = NULL; PushBack(NN, 7); PushBack(NN, 8); PushBack(NN, 9); PushBack(NN, 0); PrintNode(NN); SListNode* c1 = Intersect(LL, MM); SListNode* c2 = Intersect(LL, NN); PrintNode(c1); PrintNode(c2); } void Test11() { printf("//Test11() IntersectRing() \n"); SListNode *LL = NULL; PushBack(LL, 1); PushBack(LL, 2); PushBack(LL, 3); PushBack(LL, 4); PushBack(LL, 5); PrintNode(LL); SListNode *NN = NULL; PushBack(NN, 6); PushBack(NN, 7); PushBack(NN, 8); PushBack(NN, 9); PushBack(NN, 0); PrintNode(NN); SListNode* c1 = IntersectRing(LL, NN);//第1种 PrintNode(c1); printf("\n"); SListNode *MM = NULL;//第2种 PushBack(MM, 0); PushBack(MM, 1); MM->next->next = LL->next; SListNode* c2 = IntersectRing(LL, MM); PrintNode(c2); printf("\n"); Find(LL, 5)->next = Find(LL, 3);//第3种 SListNode* c3 = IntersectRing(LL, NN); SListNode* c4 = IntersectRing(NN, LL); PrintNode(c3); PrintNode(c4); printf("\n"); Find(NN, 0)->next = Find(NN, 8);//第4种 SListNode* c5 = IntersectRing(NN, LL); PrintNode(c5); printf("\n"); SListNode* c6 = IntersectRing(MM, LL);//第5种 SListNode* c7 = IntersectRing(LL, MM); SListNode* tmp1 = c6->next; c6->next = NULL; PrintNode(c6); c6->next = tmp1; SListNode* tmp2 = c7->next; c7->next = NULL; PrintNode(c7); c7->next = tmp2; printf("\n"); Find(NN, 0)->next = Find(LL, 4);//第6种 SListNode* c9 = IntersectRing(NN, LL); SListNode* tmp3 = c9->next; c9->next = NULL; PrintNode(c9); c9->next = tmp3; SListNode* c10 = IntersectRing(LL, NN); SListNode* tmp4 = c10->next; c10->next = NULL; PrintNode(c10); c10->next = tmp4; printf("\n"); Find(LL, 5)->next = Find(LL, 1);//第6种 Find(NN, 0)->next = Find(LL, 4); SListNode* c11 = IntersectRing(NN, LL); SListNode* tmp5 = c11->next; c11->next = NULL; PrintNode(c11); c11->next = tmp5; SListNode* c12 = IntersectRing(LL, NN); SListNode* tmp6 = c12->next; c12->next = NULL; PrintNode(c12); c12->next = tmp6; printf("\n"); }
<笔试><面试>C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)
标签:笔试 面试 c/c++ 单链表 判断两链表是否相交 求交点
原文地址:http://10739786.blog.51cto.com/10729786/1737116