하고 싶은 얘기를 마음대로 쓰는 게시판입니다. 개발 관련 이야기, 살면서 재미있었던 일, 인생 상담, 예쁘고 신기한 사진 등 마음대로 떠들어 보세요. 단, 개발관련 질문만은 별도의 게시판을 이용해 주십시오.
  • 단일 링크드 리스트 2차
  • 조회 수: 855, 추천 수: 0/0, 2016-01-15 16:19:52(2016-01-15)
  • 오늘은 검색과 삭제, 수정을 추가해 보겠습니다.


    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    #include <stdio.h>
    #include <string.h>
     
    /*
        단일 링크드 리스트
        head와 tail에 데이터를 넣지 않는 기초적인 방식.
    */
     
    // 1.구조체를 선언.
    typedef struct movie {
        char title[100];    // 타이틀
        double rating;      // 평점
        struct movie *next; // next노드
    } MOVIE;
     
    // 2.head와 tail을 전역으로 선언
    MOVIE * head = NULL;
    MOVIE * tail = NULL;
     
    // 3.movie추가
    void add_movie()
    {
        // 3-1. 새로운 movie노드 생성
        MOVIE * newMovie = new MOVIE;
     
        // 3-2. 값입력. 편의상 오류처리 하지않음.
        printf("Title:");
        
        // FIX1.검색을 위해 입력처리 변경
        //scanf("%s", newMovie->title);
        gets(newMovie->title);
     
        printf("rating:");
        scanf("%lf", &newMovie->rating);
        // FIX2.표준입력 clear처리추가.
        fflush(stdin);
        
        
     
        newMovie->next = NULL;
     
        // 3-3. 헤드가 NULL이면 첫 데이터.
        if (head == NULL)
        {
            // 헤드와 테일 모두 같은곳을 가리킨다.
            head = newMovie;
            tail = newMovie;
        }
        else
        {
            // 첫 데이터가 아니면 제일 끝 노드(테일)에 추가시킨다.
            tail->next = newMovie;  // 제일 끝 노드(테일)의 next에 newMovie를 추가.
            tail = newMovie;        // 이제 제일 끝 노드는 newMovie가 됐다.
        }
        printf("[Create NODE]. title:%s\n", newMovie->title);
    }
     
    // 4.movie보기
    void show_movie()
    {
        // 4-1. 출력대상에 head를 지정
        MOVIE * current = head;
     
        // 4-2. 출력대상이 NULL이 아닐때까지 루프
        while (current != NULL)
        {
            // 4-3. 출력.
            // FIX3.알기쉽게 리스트 문자열을 추가
            // printf("Title:%s, Rating:%lf\n", current->title, current->rating);
            printf("[LIST]Title:%s, Rating:%lf\n", current->title, current->rating);
            
            // 4-4. 출력대상에 그 다음 노드를 지정.
            current = current->next;
        }
    }
     
    // 5.movie삭제
    void clear_movie()
    {
        // 5-1. 삭제대상에 head를 지정
        MOVIE * current = head;
        MOVIE * temp = NULL;
     
        // 5-2. 삭제대상이 NULL이 아닐때까지 루프
        while (current != NULL)
        {
            // 5-3. 삭제대상의 다음 노드를 미리 확보.
            temp = current->next;
     
            // 5-4. 삭제대상을 삭제
            printf("[Remove NODE]. title:%s\n", current->title);
            delete current;
     
            // 5-5. 확보했던 노드를 설정
            current = temp;
        }
    }
     
    // 6-2. 타이틀인 경우
    void search_movie(const char * title)
    {
        // 6-2-1. head부터 검색시작
        MOVIE * current = head;
     
        while (current != NULL)
        {
            // 6-2-2. 검색하고자 하는 문자열이 포함된 모든 영화를 출력.
            if (strstr(current->title, title) != NULL)
            {
                printf("[SEARCH RESULT]Title:%s, Rating:%lf\n", current->title, current->rating);
            }
            // 6-2-3. 다음 노드로 이동.
            current = current->next;
        }
    }
    // 6-3. 평점인 경우
    void search_movie(double rating)
    {
        // 6-3-1. head부터 검색시작
        MOVIE * current = head;
     
        while (current != NULL)
        {
            // 6-3-2. 검색하고자 평점과 동일하거나 그 이상의 모든 영화를 출력.
            if (current->rating >= rating)
            {
                printf("[SEARCH RESULT]Title:%s, Rating:%lf\n", current->title, current->rating);
            }
            // 6-3-3. 다음 노드로 이동.
            current = current->next;
        }
    }
     
    // 6.movie검색
    void search()
    {
        int select = 0;
     
        // 6-1. 뭘로 검색할건지 지정. 오류검사 생략
        printf("select the search item. (1)title (2)rating (0)cancel:");
        scanf("%d", &select);
        fflush(stdin);
     
        if (select == 1)
        {
            // 6-2. 타이틀인 경우
            char title[100];
            printf("enter the title to search:");
            gets(title);
     
            search_movie(title);
        }
        else if (select == 2)
        {
            // 6-3. 평점인 경우
            double rating;
            printf("enter the rating to search:");
            scanf("%lf", &rating);
            fflush(stdin);
     
            search_movie(rating);
        }
    }
     
    // 7.movie선택삭제
    void remove_movie()
    {
        char title[100];
     
        // 7-1. 타이틀로 삭제. 오류 검사는 생략.
        printf("enter the movie title to delete:");
        gets(title);
     
        // 7-2. 현재 노드와 이전노드를 준비.
        MOVIE * prev = NULL;
        MOVIE * current = head;
     
        while (current != NULL)
        {
            // 7-3. 삭제하고자 하는 타이틀과 완전히 일치할 경우
            if (strcmp(current->title, title) == 0)
            {
                // 7-4. head이자 tail이면 데이터가 1개뿐일 경우
                if (current == head && current == tail)
                {
                    // head와 tail을 초기화시키고, current를 삭제.
                    head = NULL;
                    tail = NULL;
     
                    printf("[Remove NODE]. title:%s\n", current->title);
                    delete current;
                    break;
                }
                // 7-5. 삭제 데이터가 head인 경우
                else if (current == head)
                {
                    // head에 다음 node를 지정하고, current를 삭제.
                    head = current->next;
     
                    printf("[Remove NODE]. title:%s\n", current->title);
                    delete current;
                    break;
                }
                // 7-6. 삭제 데이터가 tail인 경우
                else if (current == tail)
                {
                    // tail에 이전 노드를 지정하고, current를 삭제.
                    tail = prev;
                    tail->next = NULL;
                    
                    printf("[Remove NODE]. title:%s\n", current->title);
                    delete current;
                    break;
                }
                // 7-7. 삭제 데이터가 head와 tail중간의 노드인 경우
                else
                {
                    // 이전 노드의 next를 현 노드의 next를 지정하고, current를 삭제
                    prev->next = current->next;
                    //          prev    current
                    // [head]->[node1]->[node2]->[tail]이라 가정할 경우.
                    //           prev
                    // [head]->[node1]->[tail]
                    //          current
                    //         [node2]->[tail]가 된 상태이므로 current를 삭제
     
                    printf("[Remove NODE]. title:%s\n", current->title);
                    delete current;
                    break;
                }
            }
            else
            {
                // 일치하지 않을 경우 current에 다음 노드를 지정
                prev = current;
                current = current->next;
            }
        }
    }
     
    // 8.수정
    void edit_movie()
    {
        char title[100];
        double rating;
        MOVIE * current = head;
     
        printf("enter the moive title to edit:");
        gets(title);
     
        while (current != NULL)
        {
            if (strcmp(current->title, title) == 0)
            {
                printf("input new title:");
                gets(title);
     
                printf("input new rating:");
                scanf("%lf", &rating);
                fflush(stdin);
     
                printf("[EDIT]%s(%lf)->%s(%lf)\n", current->title, current->rating, title, rating);
                
                strcpy(current->title, title);
                current->rating = rating;
                return;
            }
            current = current->next;
        }
        printf("[EDIT] target not found.\n");
    }
     
    int main()
    {
        for (int i = 0; i < 4; i++)
        {
            // 3.movie추가
            add_movie();
        }
        
        // 6.movie검색
        search();
     
        // 4.movie보기
        show_movie();
     
        // 7.movie선택삭제
        remove_movie();
        show_movie();
     
        // 8.수정
        edit_movie();
        show_movie();
     
        // 5.movie삭제
        clear_movie();
     
        getchar();
        return 0;
    }
     
    cs


    이것으로 기본적인 추가, 보기, 검색, 수정, 삭제는 완료된 상태입니다.

    그런데 코드를 보면 수정할 점이 많이 보이네요.


    1. 검색, 수정, 삭제는 대상을 검색해야 한다는 공통점이 있으니 검색함수 하나를 빼서 간결하게 만들면 좋을듯 싶구요.

    2. 좀더 프로그램 답게 메뉴를 제공해서 유저의 입력을 받고, 파일 입출력을 통해서 데이터 저장&로드를 해보도록 하면 좋을듯 싶습니다.



댓글 0

현재 게시판 기능 테스트중입니다. 디자인이나 게시판 구성은 언제든지 예고없이 변경될 수 있습니다.