How do I check whether a link exists on a one-way linked list?

Source: Internet
Author: User

1. The simplest method is to use a pointer to a traversal table. Every time a node is encountered, its memory address (in Java, objects can be used. put hashcode () as a key in a hashtable. in this case, when duplicate keys appear in hashtable, it indicates that the linked list has loops. the time complexity of this method is O (n), and the space is also O (n ).

2. Use the reverse pointer method to reverse the pointer of a node every time a node exists:

Boolean 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;}

It seems that this is a strange method: when there is a ring, the next pointer will eventually go to the head of the linked list; when there is no ring, the next pointer will reverse the structure of the linked list (reverse the linked list ), so we 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 biggest disadvantage of this method is that it is not safe in the case of multithreading. When multiple threads are reading the linked list, the check loop thread will change the state of the linked list, although we finally restored the structure of the linked list itself, other threads cannot guarantee correct results.

3. This is what the average interviewer expects: Fast pointer and slow pointer.

Boolean has_loop(Node *head) {    Node *pf = head; /* fast pointer */    Node *ps = head; /* slow pointer */    while(true) {        if(pf && pf->next)            pf = pf->next->next;        else            return FALSE;        ps = ps->next;        if(ps == pf)            return TRUE;    }}

It should be noted that when the slow pointer (PS) enters the ring, it will take up to n-1 steps to meet the fast pointer (PF), where N is the length of the ring. that is to say, the fast pointer can not skip the slow pointer in the ring, which can be proved simply by induction.
(1) When PS in the ring position I, and PF in the ring position I-1, in the next iteration, PS will meet PF in I + 1.
(2) When PS in the ring position I, and PF in the ring position I-2, in the next iteration, PS in I + 1, PF in I, so the next iteration PS and PF will meet at the I + 2 position.
(3) similar to the above reasoning process, when PS is in I and PF is in I + 1, they will pass through n-1 iteration and encounter at I + n-1. therefore, the number of slow pointer steps does not exceed n-1.

Extension:

There are still some extensions to this question. For example, how can we find the starting node of the ring? How to unlock this ring? The essence of these problems is how to find the node with "edge.

We can solve this problem by using a deformation in method 3:

Boolean has_loop(Node *head) {    Node *pf = head; /* fast pointer */    Node *ps = head; /* slow pointer */    while(true) {  /* step 1, is there a loop? */        if(pf && pf->next)            pf = pf->next->next;        else            return FALSE;        ps = ps->next;        if(ps == pf)            break;    }    /* step 2, how long is the loop */    int i = 0;    do {        ps = ps->next;        pf = pf->next->next;        i++;    } while(ps!=pf)    /* step 3, use 2 addtional pointers with distance i to break the loop */    ps = head;    pf = head;    int j;    for(j=0; j<i; j++) { pf = pf->next; }    j = 0;    while(ps!=pf) {        ps = ps->next;        pf = pf->next;        j++;    }    printf("loop begins at position %d, node address is %x", j, ps);    /*step 4, break the loop*/    for(j=0; j<=i; j++) { ps = ps->next; } //step i-1 in the loop from loop beginning    ps->next = NULL; // break the loop    return TRUE;}

How do I check whether a link exists on a one-way linked list?

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.