ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [05]C언어 연결리스트 :: 단일연결리스트 데이터 탐색/삭제/출력
    IT&컴퓨터공학/자료구조&알고리즘 2019. 2. 12. 16:42


    • 데이터 탐색


    이러한 단일연결리스트가 있을때 데이터 탐색을 해볼까요 ?

    탐색은 아주 쉬워요 !



    데이터 탐색의 과정은 위 그림처럼

    Cur 이라는 노드 포인터로 Head 다음부터 마지막 NULL 까지 차례대로 넘어가면서 찾는 데이터가 있으면 출력하고, 

    없으면 원하는 데이터가 없다고 출력합니다.


    이 과정을 코드로 나타내보면


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    void Search(List *L, int number)
    {
        Node *cur = L->head; // cur 이 리스트의 head를 가르킨다. 
     
        if (L->head->next == NULL
        {
            printf("저장된 데이터가 없습니다 !\n");
        }
        else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 )
        {
            while (cur!=NULL//cur 이 NULL 을 만나면 while문을 나간다.
            {
                if (cur->data == number) //cur 이 가르키는 데이터가 찾는 데이터이면
                {
                    printf("%d\n", number); //출력하고
                    return// 종료한다
                }
                cur = cur->next; // 아니면 다음데이터로
            }
            if (cur == NULLprintf("찾는 데이터가 없습니다!\n"); // NULL 까지 
        }
    }
    cs


    이렇게 나타낼 수 있겠네요 !


    • 데이터 삭제



    위의 사진에서 20이라는 노드를 삭제하는 과정은,


    ① 20이라는 노드를 찾는다. ( 위의 데이터 탐색을 사용해서 )

    ② 20이라는 노드의 뒤에 노드와 앞의 노드를 연결시켜주고

    ③ 20이라는 노드는 free를 해준다.


    이렇게 되겠네요 !


    그럼 한 번 그림으로 볼까요 ?

    이렇게 cur이라는 포인터가 20을 찾았을 때,


    앞의 노드와 뒤의 노드 ( 30 과 10 ) 을 어떻게 연결해 줄 수 있을까요 ?

    10은 cur->next 로하면 될거같은데 , 30은 ?


    위의 방법처럼 하면 30을 나타낼 수 있는 방법이 없어요 !


    그래서



    이렇게 cur->next 가 우리가 찾는 20이어야 합니다.

    cur은 우리가 찾는 노드의 바로 전 노드로 하면 되겠죠 ?


    이 과정을 코드로 나타내보면,


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    void Remove(List *L, int number)
    {
        Node *cur = L->head;
        Node *rpos; // free 될 노드를 가르킬 노드
     
        if (L->head->next == NULL// 데이터가 하나도없으면
        {
            printf("저장된 데이터가 없습니다 !\n");
        }
        
        else // 데이터가 하나라도 있다면
        {
            while (cur->next != NULL//cur의 next가 null이 아니면 계속 돈다
            {
                if (cur->next->data == number)
                {
                    rpos = cur->next; // cur->next를 free 시켜야 하므로
                    cur->next = cur->next->next; // 앞의 노드가 가르키는게(cur->next) 뒤(cur->next->next)의 노드이다.
                    free(rpos); // free
                    return;
                }
                cur = cur->next;
            }
            if (cur->next == NULLprintf("찾는 데이터가 없습니다!\n");
        }
    }
    cs


    이렇게 되겠네요 ! 위에서 본 탐색과 비슷하죠?


    • 데이터 출력
    데이터 출력은 정말 쉬운데요 !
    이건 따로 설명없이 코드만 보셔도 충분히 이해하실 수 있을것 같습니다 !

    코드를 써보자면,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void Print(List *L)
    {
        Node *cur;
     
        if (L->head->next == NULLprintf(" 저장된 데이터가 없습니다 !\n");
        else
        {
            cur = L->head->next;
            while (cur != NULL)
            {
                printf(" %d", cur->data);
                cur = cur->next;
            }
        }
    }
    cs


    이렇게 나타낼 수 있겠네요 .



    앞에서 봤던 단일연결리스트의 초기화/삽입/탐색/삭제/출력의 모든 코드를 합쳐보면


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    #include <stdio.h>
    #include <stdlib.h>
     
     
    typedef struct _Node {
        int data;   // int 형 데이터를 담는공간
        struct _Node *next; // 연결의 도구 ! ( 화살표 )
    }Node;
     
    typedef struct _List{
        Node *head;
        int numofData;
    }List;
     
    Node* getNode()
    {
        Node *new = (Node*)malloc(sizeof(Node));
        new->next = NULL;
     
        return new;
    }
     
    List* initList()
    {
        List *= (List*)malloc(sizeof(List));
        L->head = getNode();
        L->numofData = 0;
        return L;
    }
     
     
    void Insert(List *L, int number)
    {
        Node *newNode = getNode();
        newNode->data = number;
     
        if (L->head->next == NULL// head 의 next가 가르키는것이 NULL 이면
        {
            newNode->next = NULL;
            L->head->next = newNode;
        }
        else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 )
        {
            newNode->next = L->head->next;
            L->head->next = newNode;
        }
    }
     
    void Search(List *L, int number)
    {
        Node *cur = L->head; // cur 이 리스트의 head를 가르킨다. 
     
        if (L->head->next == NULL
        {
            printf("저장된 데이터가 없습니다 !\n");
        }
        else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 )
        {
            while (cur!=NULL)
            {
                if (cur->data == number)
                {
                    printf("%d\n", number);
                    return;
                }
                cur = cur->next;
            }
            if (cur == NULLprintf("찾는 데이터가 없습니다!\n");
        }
    }
     
    void Remove(List *L, int number)
    {
        Node *cur = L->head;
        Node *rpos; // free 될 노드를 가르킬 노드
     
        if (L->head->next == NULL// 데이터가 하나도없으면
        {
            printf("저장된 데이터가 없습니다 !\n");
        }
        
        else // 데이터가 하나라도 있다면
        {
            while (cur->next != NULL//cur의 next가 null이 아니면 계속 돈다
            {
                if (cur->next->data == number)
                {
                    rpos = cur->next; // cur->next를 free 시켜야 하므로
                    cur->next = cur->next->next; // 앞의 노드가 가르키는게(cur->next) 뒤(cur->next->next)의 노드이다.
                    free(rpos); // free
                    return;
                }
                cur = cur->next;
            }
            if (cur->next == NULLprintf("찾는 데이터가 없습니다!\n");
        }
    }
     
    void Print(List *L)
    {
        Node *cur;
     
        if (L->head->next == NULLprintf(" 저장된 데이터가 없습니다 !\n");
        else
        {
            cur = L->head->next;
            while (cur != NULL)
            {
                printf(" %d", cur->data);
                cur = cur->next;
            }
        }
    }
    cs


    이렇게 되겠네요 !

    댓글

Designed by Tistory.