Programming/C C++

Cycle Detection

728x90

https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle/problem

 

Cycle Detection | HackerRank

Given a pointer to the head of a linked list, determine whether the linked list loops back onto itself

www.hackerrank.com

[DataStructure/Medium]

연결리스트 내에 cycle이 있는지 boolean값으로 리턴하는 함수 has_cycle()을 작성하는 문제

head 노드를 인자로 받고 그 노드를 기준으로 연결리스트를 탐색하며 cycle이 있는지 확인해야한다.

 

함수 내부에 주석처리를 한 코드는 timeout으로 종료된 코드이다. 

tmp1, tmp2를 선언하고 head 노드로 초기화한다. 만약 두 노드가 NULL 값이거나 그 다음노드 (next; 노드가 가리키는 다음 노트)가 NULL이라면 cycle이 없는 채로 연결리스트가 종료되는 상황이기 때문에 이를 while문의 조건으로 한다. 

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* readline();

typedef struct SinglyLinkedListNode SinglyLinkedListNode;
typedef struct SinglyLinkedList SinglyLinkedList;

struct SinglyLinkedListNode {
    int data;
    SinglyLinkedListNode* next;
};

struct SinglyLinkedList {
    SinglyLinkedListNode* head;
    SinglyLinkedListNode* tail;
};

SinglyLinkedListNode* create_singly_linked_list_node(int node_data) {
    SinglyLinkedListNode* node = malloc(sizeof(SinglyLinkedListNode));

    node->data = node_data;
    node->next = NULL;

    return node;
}

void insert_node_into_singly_linked_list(SinglyLinkedList** singly_linked_list, int node_data) {
    SinglyLinkedListNode* node = create_singly_linked_list_node(node_data);

    if (!(*singly_linked_list)->head) {
        (*singly_linked_list)->head = node;
    } else {
        (*singly_linked_list)->tail->next = node;
    }

    (*singly_linked_list)->tail = node;
}

void print_singly_linked_list(SinglyLinkedListNode* node, char* sep, FILE* fptr) {
    while (node) {
        fprintf(fptr, "%d", node->data);

        node = node->next;

        if (node) {
            fprintf(fptr, "%s", sep);
        }
    }
}

void free_singly_linked_list(SinglyLinkedListNode* node) {
    while (node) {
        SinglyLinkedListNode* temp = node;
        node = node->next;

        free(temp);
    }
}

// Complete the has_cycle function below.

/*
 * For your reference:
 *
 * SinglyLinkedListNode {
 *     int data;
 *     SinglyLinkedListNode* next;
 * };
 *
 */
bool has_cycle(SinglyLinkedListNode* head) {
    SinglyLinkedListNode *tmp1;
    SinglyLinkedListNode *tmp2;

    tmp1=head;
    tmp2=head;

    while((tmp1!=NULL)&&(tmp2!=NULL)&&(tmp2->next !=NULL))//tmp2가 먼저 가는 링크노트
    {
        tmp1=tmp1->next;
        tmp2=(tmp2->next)->next;
        if(tmp2==tmp1)  return true;
    }
    return false;
    /*if(head->next ==NULL)
        return false;
    else{ //NULL을 가리키지 않는 경우 - cycle이 있는경우와 없는 경우
    if((head->next)->next == head)
        return true;
    else {
    return has_cycle(head->next);
        }
    }*/


}

int main()

    FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");

    char* tests_endptr;
    char* tests_str = readline();
    int tests = strtol(tests_str, &tests_endptr, 10);

    if (tests_endptr == tests_str || *tests_endptr != '\0') { exit(EXIT_FAILURE); }

    for (int tests_itr = 0; tests_itr < tests; tests_itr++) {
        char* index_endptr;
        char* index_str = readline();
        int index = strtol(index_str, &index_endptr, 10);

        if (index_endptr == index_str || *index_endptr != '\0') { exit(EXIT_FAILURE); }

        SinglyLinkedList* llist = malloc(sizeof(SinglyLinkedList));
        llist->head = NULL;
        llist->tail = NULL;

        char* llist_count_endptr;
        char* llist_count_str = readline();
        int llist_count = strtol(llist_count_str, &llist_count_endptr, 10);

        if (llist_count_endptr == llist_count_str || *llist_count_endptr != '\0') { exit(EXIT_FAILURE); }

        for (int i = 0; i < llist_count; i++) {
            char* llist_item_endptr;
            char* llist_item_str = readline();
            int llist_item = strtol(llist_item_str, &llist_item_endptr, 10);

            if (llist_item_endptr == llist_item_str || *llist_item_endptr != '\0') { exit(EXIT_FAILURE); }

            insert_node_into_singly_linked_list(&llist, llist_item);
        }
      
      	SinglyLinkedListNode* extra = create_singly_linked_list_node(-1);
      	SinglyLinkedListNode* temp = llist->head;
      
      	for (int i = 0; i < llist_count; i++) {
            if (i == index) {
          		extra = temp;
            }
          	
          	if (i != llist_count-1) {
          		temp = temp->next;
            }
        }
      
      	temp->next = extra;

        bool result = has_cycle(llist->head);

        fprintf(fptr, "%d\n", result);
    }

    fclose(fptr);

    return 0;
}

char* readline() {
    size_t alloc_length = 1024;
    size_t data_length = 0;
    char* data = malloc(alloc_length);

    while (true) {
        char* cursor = data + data_length;
        char* line = fgets(cursor, alloc_length - data_length, stdin);

        if (!line) { break; }

        data_length += strlen(cursor);

        if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') { break; }

        size_t new_length = alloc_length << 1;
        data = realloc(data, new_length);

        if (!data) { break; }

        alloc_length = new_length;
    }

    if (data[data_length - 1] == '\n') {
        data[data_length - 1] = '\0';
    }

    data = realloc(data, data_length);

    return data;
}

 

 

SMALL

'Programming > C C++' 카테고리의 다른 글

Queue using Two Stacks  (0) 2020.06.14
Mini-Max Sum  (0) 2020.06.14
Merge two sorted linked lists  (0) 2020.06.08
Balanced Brackets  (0) 2020.06.07
PreOrder/InOrder/PostOrder  (0) 2020.05.29