이 튜토리얼에서는 단일 연결 리스트(Singly Linked List)에서 소수(prime) 값을 가진 노드를 모두 삭제하는 방법을 알아보겠습니다.
먼저 문제를 해결하기 위한 전체적인 흐름을 살펴보겠습니다.
문제 해결 단계
데이터(data)와 다음 노드 포인터(next)를 가지는 구조체(struct)를 정의합니다.
단일 연결 리스트에 새 노드를 삽입하는 함수를 작성합니다.
테스트용 더미 데이터로 단일 연결 리스트를 초기화합니다.
연결 리스트를 처음부터 끝까지 순회하며, 현재 노드의 데이터가 소수인지 판별합니다.
현재 데이터가 소수라면 해당 노드를 삭제합니다.
노드를 삭제하는 별도의 함수를 작성합니다. 노드를 삭제할 때는 아래 세 가지 경우를 반드시 고려해야 합니다.
헤드(head) 노드인 경우: 헤드 포인터를 다음 노드로 이동시킵니다.
중간 노드인 경우: 이전 노드의 next 포인터를 다음 노드에 연결합니다.
마지막 노드인 경우: 이전 노드의 링크(next 포인터)를 제거합니다.
구현 예제 코드
위의 단계를 바탕으로 작성한 전체 코드입니다.
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *next;
};
void insertNode(Node** head_ref, int new_data) {
Node* new_node = (Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
bool isPrime(int n) {
if (n <= 1) {
return false;
}
if (n <= 3) {
return true;
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
for (int i = 5; i * i <= n; i = i + 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
void deleteNode(Node** head_ref, Node* del) {
struct Node* temp = *head_ref;
if (*head_ref == NULL || del == NULL) {
return;
}
if (*head_ref == del) {
*head_ref = del->next;
}
while (temp->next != del) {
temp = temp->next;
}
temp->next = del->next;
free(del);
return;
}
void deletePrimeNodes(Node** head_ref) {
Node* temp = *head_ref;
Node* next;
while (temp != NULL) {
next = temp->next;
if (isPrime(temp->data)) {
deleteNode(head_ref, temp);
}
temp = next;
}
}
void printLinkedList(Node* head) {
while (head != NULL) {
cout << head->data << " -> ";
head = head->next;
}
}
int main() {
Node* head = NULL;
insertNode(&head, 1);
insertNode(&head, 2);
insertNode(&head, 3);
insertNode(&head, 4);
insertNode(&head, 5);
insertNode(&head, 6);
cout << "Linked List before deletion:" << endl;
printLinkedList(head);
deletePrimeNodes(&head);
cout << "\nLinked List after deletion:" << endl;
printLinkedList(head);
}실행 결과
위 프로그램을 실행하면 다음과 같은 결과를 얻을 수 있습니다.
Linked List before deletion: 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> Linked List after deletion: 6 -> 4 -> 1 ->
코드 핵심 포인트
isPrime 함수: 6k±1 최적화 기법을 사용하여 제곱근까지만 검사함으로써 소수 판별 속도를 높였습니다.
deleteNode 함수: 삭제 대상 노드가 헤드 노드인지 여부를 먼저 확인한 뒤, 이전 노드를 찾아 링크를 재조정하고 메모리를 해제(free)합니다.
deletePrimeNodes 함수: 노드를 삭제하기 전에 미리 다음 노드의 주소를 저장해 두기 때문에, 삭제 후에도 안전하게 순회를 계속할 수 있습니다.
마무리
이 튜토리얼에 대해 궁금한 점이나 추가 질문이 있다면 댓글로 남겨주세요.