SListNode* IsRing(SListNode *&pHead) //判断链表是否有环,求相聚点 { //判空、有、没有 //思路:两个指针从头开始一快(2步)一慢(1步),若最后可以相聚,则链表有环 if (pHead) { SListNode *fast = pHead; SListNode *slow = pHead; while (fast&&fast->next) { fast = fast->next->next; slow = slow->next; if (slow == fast) return fast; } return NULL; } return NULL; } int RingLength(SListNode *&pHead)//求链表环长度 { //先判断链表有环 //思路:从IsRing得到的点开始走一圈环,记录结点个数 if (pHead)//判空 { SListNode* point = IsRing(pHead); if (point != NULL)//无环情况 { int count = 1; SListNode *tmp = point->next; while (tmp != point) { tmp = tmp->next; count++; } return count; } } return 0; } SListNode* RingEntry(SListNode *&pHead)//找环入口 { //判是否为空、有环 //思路:判断有环,找到快慢指针的相聚点,然后一个指针从聚点开始,一个从头开始,每次一步,相遇点就为入口节点 if (pHead)//判空 { SListNode *tmp = IsRing(pHead); if (tmp)//判有环 { SListNode *cur = pHead; while (cur!=tmp) { cur = cur->next; tmp = tmp->next; } return cur; } return NULL; } return NULL; } int _LengthNode(SListNode*& pHead)//RingEntry_Point内部函数,求链表长度 { if (pHead) { SListNode *tmp = pHead; int count = 0; while (tmp) { count++; tmp = tmp->next; } return count; } return 0; } SListNode* RingEntry_Point(SListNode *&pHead)//找环入口_链表相交法 { //判是否为空、有环 //思路:在快慢指针相聚点截断,将环链表变为两个相交链表,因为相交链表尾部重合呈Y字型, // 求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短链表头开始, // 两链表一起走,相遇点就为入口点 // //经过调试发现 当整个链表呈环时,为特殊情况 if (pHead)//判空 { SListNode *tmp = IsRing(pHead); if (tmp)//判有环 { SListNode *cur = pHead; SListNode *NewNode = tmp->next; tmp->next = NULL; 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 = NewNode->next; cur = cur->next; } return cur; } return NULL; } return NULL; } void Test9() //IsRing/RingLength/RingEntry_1/RingEntry_2 { printf("//Test9() IsRing/RingLength/RingEntry/RingEntry_Point \n"); SListNode *LL = NULL; PushBack(LL, 1); PushBack(LL, 2); PushBack(LL, 3); PushBack(LL, 4); PushBack(LL, 5); PrintNode(LL); //printf("%d\n", _LengthNode(LL)); printf("\nRingLength = %d\n", RingLength(LL));//不是环 SListNode*tmp = RingEntry(LL); PrintNode(tmp); tmp = RingEntry_Point(LL); PrintNode(tmp); Find(LL, 5)->next = Find(LL, 5);//尾结点呈环 printf("\nRingLength = %d\n", RingLength(LL)); printf("RingEntry = %d\n", RingEntry(LL)->data); printf("RingEntry_Point = %d\n", RingEntry_Point(LL)->data); Find(LL, 5)->next = Find(LL, 3);//中间结点开始呈环 printf("\nRingLength = %d\n", RingLength(LL)); printf("RingEntry = %d\n", RingEntry(LL)->data); printf("RingEntry_Point = %d\n", RingEntry_Point(LL)->data);//函数RingEntry_Point在此处将原链表破坏丢失元素5 //Find(LL, 5)->next = Find(LL, 1);//整个链表为环链表已不存在元素为5的结点 出现错误 Find(LL, 4)->next = Find(LL, 1);//整个链表为环 printf("\nRingLength = %d\n", RingLength(LL)); printf("RingEntry = %d\n", RingEntry(LL)->data); printf("RingEntry_Point = %d\n", RingEntry_Point(LL)->data); }
时间: 2024-10-26 12:09:02