How to check the loop in the linked list in C + +? These five plans are really amazing!

Time:2021-7-18

Through 5 solutions to teach you c + + in the detection of loop in the list, come to see if it helps you!

 

Given a linked list, check whether there is a loop in the linked list. The following figure shows a linked list with loops.

 

Here are the different ways to do this

Solution 1: hash method

Traverse the list and always put the node address in the hash table. At any time, it returns false if NULL is reached, and true if the next node of the current node points to any node previously stored in the hash.

#include  

using namespace std; 

struct Node { 

    int data; 

    struct Node* next; 

}; 

 

void push(struct Node** head_ref, int new_data) 

    struct Node* new_node = new Node; 

    new_node->data = new_data; 

    new_node->next = (*head_ref); 

    (*head_ref) = new_node; 

bool detectLoop(struct Node* h) 

    unordered_set s; 

    while (h != NULL) { 

        if (s.find(h) != s.end()) 

            return true; 

        s.insert(h); 

 

        h = h->next; 

    } 

 

    return false; 

int main() 

    struct Node* head = NULL; 

 

    push(&head, 20); 

    push(&head, 4); 

    push(&head, 15); 

    push(&head, 10); 

    head->next->next->next->next = head; 

 

    if (detectLoop(head)) 

        cout <

    else 

        cout <

 

    return 0; 

Complexity analysis:

Time complexity: O (n).

Just cycle once.

Auxiliary space: O (n).

N is the space required to store the value in the hash graph.

Solution 2: by modifying the linked list data structure, this problem can be solved without hash graph.

Methods: this solution needs to modify the basic linked list data structure.

Each node has an access flag.

Traverse the list of links and continue marking the visited nodes.

If you see a visited node again, there is a loop. The solution works for O (n), but each node needs additional information.

A variant of this solution does not need to modify the basic data structure. It can be implemented by using hash. It only needs to store the address of the visited node in the hash. If you see the address that already exists in the hash, there will be a loop.

C++:

#include  

using namespace std; 

struct Node { 

    int data; 

    struct Node* next; 

    int flag; 

}; 

 

void push(struct Node** head_ref, int new_data) 

    struct Node* new_node = new Node; 

    new_node->data = new_data; 

 

    new_node->flag = 0; 

    new_node->next = (*head_ref); 

    (*head_ref) = new_node; 

bool detectLoop(struct Node* h) 

    while (h != NULL) { 

        if (h->flag == 1) 

            return true; 

        h->flag = 1; 

 

        h = h->next; 

    } 

 

    return false; 

int main() 

    struct Node* head = NULL; 

 

    push(&head, 20); 

    push(&head, 4); 

    push(&head, 15); 

    push(&head, 10); 

    head->next->next->next->next = head; 

 

    if (detectLoop(head)) 

        cout <

    else 

        cout <

 

    return 0; 

Complexity analysis:

Time complexity: O (n).

Just cycle once.

Auxiliary space: O (1).

No extra space is required.

Solution 3: Floyd’s loop search algorithm

This is the fastest way, which is described below.

Use two pointers to traverse the linked list.

Set a pointer (slow_ p) Move one pointer and set the other pointer (fast)_ p) Move two.

If these pointers meet at the same node, there is a loop. If the pointer does not meet the requirements, the link list does not loop.

Floyd’s loop search algorithm is implemented

#include  

using namespace std; 

class Node { 

public: 

    int data; 

    Node* next; 

}; 

 

void push(Node** head_ref, int new_data) 

    Node* new_node = new Node(); 

    new_node->data = new_data; 

    new_node->next = (*head_ref); 

    (*head_ref) = new_node; 

 

int detectLoop(Node* list) 

    Node *slow_p = list, *fast_p = list; 

 

    while (slow_p && fast_p && fast_p->next) { 

        slow_p = slow_p->next; 

        fast_p = fast_p->next->next; 

        if (slow_p == fast_p) { 

            return 1; 

        } 

    } 

    return 0; 

int main() 

    Node* head = NULL; 

 

    push(&head, 20); 

    push(&head, 4); 

    push(&head, 15); 

    push(&head, 10); 

    head->next->next->next->next = head; 

    if (detectLoop(head)) 

        cout <

    else 

        cout <

    return 0; 

Solution 4: mark the visited nodes without modifying the linked list data structure

In this method, a temporary node is created. Make the next pointer of each traversed node point to the temporary node. In this way, we use the next pointer of the node as a flag to indicate whether the node has been traversed. Check each node to see if the next node points to a temporary node. In the case of the first node of the loop, the second traversal of the condition will hold, so we find that the loop exists. If a node pointing to null is encountered, the loop does not exist.

The following is the implementation of the above method:

#include  

using namespace std; 

 

struct Node { 

    int key; 

    struct Node* next; 

}; 

 

Node* newNode(int key) 

    Node* temp = new Node; 

    temp->key = key; 

    temp->next = NULL; 

    return temp; 

void printList(Node* head) 

    while (head != NULL) { 

        cout <key <

        head = head->next; 

    } 

    cout <

bool detectLoop(Node* head) 

    Node* temp = new Node; 

    while (head != NULL) { 

        if (head->next == NULL) { 

            return false; 

        } 

        if (head->next == temp) { 

            return true; 

        } 

        Node* nex = head->next; 

        head->next = temp; 

        head = nex; 

    } 

 

    return false; 

int main() 

    Node* head = newNode(1); 

    head->next = newNode(2); 

    head->next->next = newNode(3); 

    head->next->next->next = newNode(4); 

    head->next->next->next->next = newNode(5); 

    head->next->next->next->next->next = head->next->next; 

 

    bool found = detectLoop(head); 

    if (found) 

        cout <

    else 

        cout <

 

    return 0; 

Complexity analysis:

Time complexity: O (n).

Just cycle once.

Auxiliary space: O (1).

There is no need for space.

Solution 5: storage length

In this method, two pointers are created, the first (always pointing to the head) and the last pointer. Every time the last pointer moves, we will calculate the number of nodes between the first and the last, and check whether the current number of nodes is greater than the previous number of nodes. If so, we will move the last pointer to operate, otherwise it means that we have reached the end of the loop, so we will return the output accordingly.

#include  

using namespace std; 

 

struct Node { 

    int key; 

    struct Node* next; 

}; 

 

Node* newNode(int key) 

    Node* temp = new Node; 

    temp->key = key; 

    temp->next = NULL; 

    return temp; 

void printList(Node* head) 

    while (head != NULL) { 

        cout <key <

        head = head->next; 

    } 

    cout <

int distance(Node* first, Node* last) 

    int counter = 0; 

 

    Node* curr; 

    curr = first; 

 

    while (curr != last) { 

        counter += 1; 

        curr = curr->next; 

    } 

 

    return counter + 1; 

bool detectLoop(Node* head) 

    Node* temp = new Node; 

 

    Node *first, *last; 

    first = head; 

    last = head; 

    int current_length = 0; 

    int prev_length = -1; 

 

    while (current_length > prev_length && last != NULL) { 

          prev_length = current_length; 

        current_length = distance(first, last); 

        last = last->next; 

    } 

 

    if (last == NULL) { 

        return false; 

    } 

    else {  

        return true; 

    } 

int main() 

    Node* head = newNode(1); 

    head->next = newNode(2); 

    head->next->next = newNode(3); 

    head->next->next->next = newNode(4); 

    head->next->next->next->next = newNode(5); 

    head->next->next->next->next->next = head->next->next; 

 

    bool found = detectLoop(head); 

    if (found) 

        cout <

    else 

        cout <

 

    return 0; 

Thank you for reading. I hope I can help you. If you have any questions, please leave a message in the comment area.

 

If you want to better improve your programming ability, learn C language c + + programming! Overtaking on the curve, one step faster!

C language c + + Learning Circle】, sharing (source code, project video, project notes, basic introductory course)

Welcome to change and learn programming partners, use more information to learn and grow faster than their own thinking Oh!

Programming books:

 

Programming learning video: