glib 라이브러리는 기본적인 데이터 구조를 제공합니다. 단일 연결 리스트, 이중 연결 리스트, 큐, 트리, 해시 테이블 및 배열 등이 포함됩니다. 이 글에서는 Linux 플랫폼에서 glib의 단일 연결 리스트(GSList) 사용법을 중심으로 설명합니다. 향후 글에서는 이중 연결 리스트, 큐 및 기타 데이터 구조에 대해 다룰 예정입니다.
단일 연결 리스트(GSList)는 glib에서 가장 간단한 자료구조입니다. 이는 여러 노드를 순차적으로 연결하여 다음 노드에 접근할 수 있도록 설계되었습니다. GSList 구조체는 다음과 같이 정의됩니다:
struct GSList {
gpointer data;
GSList *next;
};
data 멤버는 void 포인터(gpointer) 형식으로, 다양한 데이터 타입을 저장할 수 있습니다. 아래 예제를 통해 GSList를 생성, 추가, 삽입, 정렬, 반전 및 해제하는 방법을 알아보겠습니다.
#include <glib.h>
void print_list(GSList *head) {
GSList *current = NULL;
for (current = head; current; current = current->next) {
printf(" %s ", (char *)current->data);
}
printf("\n");
}
int string_compare(gconstpointer a, gconstpointer b) {
return strcmp(a, b);
}
int main(int argc, char *argv[]) {
GSList *head = NULL;
printf("단일 리스트 생성:\n");
head = g_slist_append(head, "첫 번째");
head = g_slist_append(head, "두 번째");
head = g_slist_append(head, "세 번째");
print_list(head);
printf("머리에 추가:\n");
head = g_slist_prepend(head, "처음");
head = g_slist_prepend(head, "두 번째");
head = g_slist_prepend(head, "세 번째");
print_list(head);
printf("지정된 위치 삽입:\n");
head = g_slist_insert(head, "1", 1);
head = g_slist_insert(head, "2", 2);
head = g_slist_insert(head, "3", 3);
print_list(head);
printf("정렬 삽입:\n");
head = g_slist_insert_sorted(head, "A", string_compare);
head = g_slist_insert_sorted(head, "B", string_compare);
head = g_slist_insert_sorted(head, "C", string_compare);
print_list(head);
printf("리스트 반전:\n");
head = g_slist_reverse(head);
print_list(head);
g_slist_free(head);
return 0;
}
실행 결과:
단일 리스트 생성:
첫 번째 두 번째 세 번째
머리에 추가:
세 번째 두 번째 처음 첫 번째 두 번째 세 번째
지정된 위치 삽입:
세 번째 1 2 3 두 번째 처음 첫 번째 두 번째 세 번째
정렬 삽입:
A B C 세 번째 1 2 3 두 번째 처음 첫 번째 두 번째 세 번째
리스트 반전:
세 번째 두 번째 처음 1 2 3 C B A
다음 예제는 단일 연결 리스트의 검색, 삭제 및 병합 기능을 보여줍니다.
#include <glib.h>
void print_list(GSList *head) {
GSList *current = NULL;
for (current = head; current; current = current->next) {
printf(" %s ", (char *)current->data);
}
printf("\n");
}
int main(int argc, char *argv[]) {
GSList *head = NULL;
printf("리스트 생성:\n");
head = g_slist_append(head, "1");
head = g_slist_append(head, "2");
head = g_slist_append(head, "3");
head = g_slist_append(head, "4");
head = g_slist_append(head, "5");
print_list(head);
GSList *node = NULL;
printf("데이터 '3' 검색:\n");
node = g_slist_find(head, "3");
printf("찾은 데이터: %s\n", (char *)node->data);
printf("3번 인덱스 데이터:\n");
node = g_slist_nth(head, 2);
if (node) printf("데이터: %s\n", (char *)node->data);
printf("5번 인덱스 데이터:\n");
printf("데이터: %s\n", g_slist_nth_data(head, 4));
head = g_slist_append(head, "2");
print_list(head);
printf("데이터 '2' 삭제:\n");
head = g_slist_remove(head, "2");
print_list(head);
printf("3번 노드 삭제:\n");
node = g_slist_nth(head, 2);
head = g_slist_remove_link(head, node);
g_slist_free_1(node);
print_list(head);
GSList *another = NULL;
printf("두 번째 리스트:\n");
another = g_slist_append(another, "6");
another = g_slist_append(another, "7");
another = g_slist_append(another, "8");
print_list(another);
printf("리스트 병합:\n");
head = g_slist_concat(head, another);
print_list(head);
g_slist_free(head);
return 0;
}
실행 결과:
리스트 생성:
1 2 3 4 5
데이터 '3' 검색:
찾은 데이터: 3
3번 인덱스 데이터:
데이터: 3
5번 인덱스 데이터:
데이터: 5
1 2 3 4 5 2
데이터 '2' 삭제:
1 3 4 5 2
3번 노드 삭제:
1 3 5 2
두 번째 리스트:
6 7 8
리스트 병합:
1 3 5 2 6 7 8
glib 라이브러리의 데이터 구조 함수는 일관된 명명 규칙을 따릅니다. 예를 들어, g_컨테이너_함수 형식으로 구성되어 있습니다. 이 규칙은 향후 소개할 이중 연결 리스트, 큐, 트리, 해시 테이블 및 배열에도 적용됩니다.