언유상씨의 건전한 취미생활

[연결리스트] 원소의 삭제와 추가 - 소스 코드 본문

건전한 취미생활 - 알고리즘

[연결리스트] 원소의 삭제와 추가 - 소스 코드

언유상 2020. 5. 11. 19:30

소스코드는 다음과 같다.

 

크게 중요한 부분은 다음과 같다.

 

1. 입력 받기

과제 제출 기한 후 교내 커뮤니티에 올라온 내용을 보면 입력 받는게 가장 여려웠다는 말이 많았다.

insert a b를 어떻게 받고, 어떻게 처리할 것인가?

 

방법은 scanf의 특성을 이용해서 입력을 받으면 된다. 

scanf는 " "를 기준으로 끊기에, insert a b는 각각 "insert", "a", "b"로 입력되게 된다.

이를 이용하면,

 

scanf("%s", &order); 

        if (strcmp(order, "insert") == 0) // strcmp 함수를 이용해서 원하는 명령인지를 판별한다.

                scanf("%d %d", &index, &data); // index와 data를 받아준다.

 

2. 원소 추가, 삭제

 

단일 연결리스트의 작동 방식을 생각해서 짜면 된다.

자세한건 소스 코드를 보면서 알아가도록 하자.

 

 

/*
********************************************
제목 : 과제5 실습과제
목표 : 영희를 도와줄 프로그램을 작성하자.
********************************************
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
typedef int element;
typedef int ind;
typedef struct ListNode { // 노드를 정의한다.
    element data;
    struct ListNode* link;
}ListNode;

ListNode* createNode(int data) // 새로운 노드를 만든다.
{
    ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
    temp->link = NULL; // 마지막 노드임으로 NULL을 가르킨다.
    temp->data = data; // 데이터 넣어주기
    return temp;

}
void plusNode(ListNode** head, ind k, element x) { // 노드 추가 함수
    ListNode* newNode = createNode(x); // 새로운 노드를 만든다.
    int cnt = 0;
    if (*head == NULL) { // 노드가 없는 상태일 경우
        *head = newNode;
    }

    else { // 노드가 있는 경우
        ListNode* temp = *head;

        if (k == 0) { // 리스트의 맨 앞에 노드를 넣는 경우
            newNode->link = temp;
            *head = newNode;
        }

        else { // 리스트의 나머지 부분에 노드를 넣는 경우
            while (cnt != k - 1) // 원하는 위치까지 찾아가는 루프
            {
                temp = temp->link;
                cnt++;
            }
            newNode->link = temp->link;
            temp->link = newNode;
        }

    }
}

void deleteNode(ListNode** head, ind x) { // 원소 삭제 함수
    int cnt = 0;
    ListNode* temp = *head;
    if (x == 0) { // 첫번째 노드를 삭제하는 경우
        *head = temp->link;
        free(temp); // 메모리 해제
    }
    else { // 나머지 위치의 노드를 삭제하는 경우
        while (cnt != x - 1) { // 원하는 위치까지 찾아가는 루프
            temp = temp->link;
            cnt++;
        }
        ListNode* deleteNode = temp->link;
        temp->link = deleteNode->link;
        free(deleteNode);  // 메모리 해제
    }
}

void printList(ListNode* head) { // 리스트 전체 출력

    for (ListNode* p = head; p != NULL; p = p->link) // 처음부터 끝까지 돌며 출력하는 루프
        printf("%d ", p->data);
    printf("\n");
}
int main(void) {
    ListNode* head = NULL;

    int number;
    int index, data;
    char order[10];
    printf("명령의 개수: ");
    scanf("%d", &number);
    for (int i = 0; i < number; i++) { // 명령 받는 루프
        scanf("%s", &order);

        if (strcmp(order, "insert") == 0) { // insert 명령어
            scanf("%d %d", &index, &data);
            plusNode(&head, index - 1, data);
        }

        else if (strcmp(order, "delete") == 0) { // delete 명령어
            scanf("%d", &index);
            deleteNode(&head, index - 1);
        }

        else if (strcmp(order, "show") == 0) { // show 명령어
            printList(head);
        }
    }
    printList(head); // 최종 형태 출력
    return 0;
}

 

실행 결과

더 효율적인 코드가 있거나, 위 코드에서 문제를 발견시 댓글로 부탁드리겠습니다!

 

Comments