Determine whether a single-chain table has a ring and the entry point for searching the ring

Source: Internet
Author: User

There are several solutions to determine whether a linked list has a ring:
1. In a traversal table, a node that has been traversed is placed in a hash table. If a node already exists in a hash table, a ring exists. Time: O (n) Space: O (N)
2. Reverse the linked list. Time O (N), Space O (1), use three pointers. (Ref: http://www.cppblog.com/tx7do/archive/2009/01/06/71280.html)

Single-chain table reversal: Two possible implementations are provided below.

Normal version:

Void reverse (node * & head) {If (Head = 0) | (Head-> next = 0) return; // Edge Detection node * pnext = 0; node * pprev = head; // Save the node * pcur = head-> next; // get the current node while (pcur! = 0) {pnext = pcur-> next; // save the next node pcur-> next = pprev; // set the next node of the current node to the previous node pprev = pcur; // Save the current node as the previous node pcur = pnext; // set the current node to the next node} head-> next = NULL; head = pprev ;}

Recursive version:

Node * reverse (node * pnode, node * & head) {If (pnode = 0) | (pnode-> next = 0 )) // recursive jump condition {head = pnode; // cut the linked list; otherwise, a return pnode will be formed;} node * temp = reserve (pnode-> next, head ); // recursion temp-> next = pnode; // set the next node to the current node, both the front node return pnode; // return to the current node}

The inverted linked list method is used to reverse the pointer of each node. If a ring exists, the next pointer is reversed and the link is finally directed to the head of the linked list. If no ring exists, the next pointer will destroy the structure of the linked list (reverse the linked list). To restore the linked list, you need to reverse the linked list again. The spatial complexity of this method is O (1). In fact, we use three additional pointers, while the time complexity is O (n ), we can traverse the entire linked list at most two times (when there is no ring in the linked list ). The following is an implementation, but the biggest problem is:If a ring exists, it cannot be restored to the original state of the linked list..

  bool reverse(Node *head) {   Node *curr = head;   Node *next = head->next;   curr->next = NULL;   while(next!=NULL) {    if(next == head) { /* go back to the head of the list, so there is a loop */      next->next = curr;      return true;    }    Node *temp = curr;    curr = next;    next = next->next;    curr->next = temp;   }   /* at the end of list, so there is no loop, let's reverse the list back */   next = curr->next;   curr ->next = NULL;   while(next!=NULL) {    Node *temp = curr;    curr = next;    next = next->next;    curr->next = temp;   }   return false;  }

3. Speed pointer. Time O (N), Space O (1), using two pointers. (Ref: http://blog.csdn.net/mingming_bupt/article/details/6331333)

Judge the existence of a ring: Set two pointers (fast and slow). The initial values are directed to the header. Slow moves one step forward each time, and fast moves two steps forward each time. If the linked list has a ring, fast must first enter the ring, and slow enters the ring, and the two pointers must meet. (Of course, if the first line to the end of fast is null, it is a non-circular linked list ).

bool IsExitsLoop(slist * head){slist * slow = head , * fast = head;while ( fast && fast -> next ){slow = slow -> next;fast = fast -> next -> next;if ( slow == fast ) break ;}return ! (fast == NULL || fast -> next == NULL);} 

Search for the entry point of the ring: When fast is followed by two steps and slow is followed by one step, it is found that fast and slow overlap, and the one-way linked list has a loop. Next, let fast return to the head of the linked list and go again. Step 1 each time. When fast and slow meet again, it is the entrance of the loop.

Proof: When fast and slow met for the first time, assuming that slow took n steps, the loop entry was in step P, then

Slow path: P + c = N; C indicates the distance between the intersection of fast and slow to the loop entry.

Fast path: P + C + K * l = 2 * n; L indicates the circumference of the loop, and K is an integer.

Obviously, if slow takes another n steps from P + C, it can return to P + C.

At the same time, fast starts from scratch. The step size is 1. After n steps, it will reach P + C.

Obviously, in this process, fast and slow only follow different paths in the previous P step. So when P1 and P2 overlap again, it must be at the loop entry point of the linked list.

slist * FindLoopPort(slist * head){slist * slow = head, * fast = head;while ( fast && fast -> next ){slow = slow -> next;fast = fast -> next -> next;if ( slow == fast ) break ;}if (fast == NULL || fast -> next == NULL)return NULL;slow = head;while (slow != fast){slow = slow -> next;fast = fast -> next;}return slow;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.