프로그램을 만들다 보면 삽입하면서 정렬이 유지돼야 될 때가 많습니다!
한 번에 삽입을 다 하고 정렬을 한다면,
배열에 모두 저장하고(O(n)) 퀵 정렬(O(nlogn)을 하는 방식으로 해결이 가능합니다.
혹은 힙에 넣고(O(n)) 힙 정렬(O(nlog))을 하는 방식을 이용하면 최댓값 삭제도 용이할 것입니다!
그런데 동적으로 삽입을 해야 되는 경우도 있습니다.
이럴 때가 바로 삽입하면서 정렬이 유지돼야 될 때입니다.
예를 들어 게임 랭킹 시스템은 레벨 별로 내림차순을 유지해야 합니다!
어떤 한 유저가 레벨을 올려서 랭킹권에 추가되더라도 내림차순은 유지돼야 합니다.
이는 자료구조(Data Structure)의 리스트를 배웠다면 쉽게 구축할 수 있습니다.
아래에 해당 프로그램 C언어 소스를 제공합니다!
설명은 주석을 참조해주세요!
시간복잡도는 O(n)을 만족합니다!
만약 일반적인 삭제가 아니라 최대/최소값 삭제만 한다면 힙(Heap)을 이용하는 편이 훨씬 좋습니다!
#include <stdio.h>
#define max 100
typedef struct {
int array[max];
int size;
}ArrayListType;
typedef ArrayListType * ArrayList_ptr;
void init(ArrayList_ptr list) {
list->size = 0;
}
int is_empty(ArrayListType list) {
if (list.size == 0)
return 1;
else
return 0;
}
int is_full(ArrayListType list) {
if (list.size == max)
return 1;
else
return 0;
}
// 이진탐색으로 item이 속한 idx찾기
int search_idx(ArrayList_ptr list,int item) {
int high = list->size-1;
int low = 0;
while (low <= high) {
int mid = (low + high) / 2;
if (list->array[mid] == item)
return mid;
else if (item > list->array[mid])
low = mid + 1;
else
high = mid - 1;
}
if (low > high)
return -1;
}
void insert(ArrayList_ptr list, int item) {
if (!is_full(*list)) {
// (pos: 삽입할 올바른 위치) 찾기
int pos = 0;
for (int i = 0; i < list->size; i++) {
// 정렬이 필요한 경우
// (=) 리스트 원소들 중 item보다 큰 것이 있는 경우
if (item <= list->array[i]) {
pos = i;
// list[pos]~list[size-1]까지 뒤로 보내기
for (int i = list->size - 1; i >= pos; i--)
list->array[i + 1] = list->array[i];
break;
}
// 정렬이 필요없는 경우 (insert_last)
else if(i==list->size-1)
pos = list->size;
}
// item 삽입
list->array[pos] = item;
list->size++;
}
else
printf("리스트가 꽉 차있습니다\n");
}
// 리스트 자료구조의 delete 함수를 변형
int delete(ArrayList_ptr list, int item) {
if (!is_empty(*list)) {
int pos;
// 배열에 해당 아이템이 있는 경우
if ((pos=search_idx(list,item)) != -1) {
int tmp = list->array[pos];
for (int i = pos + 1; i < list->size; i++)
list->array[i - 1] = list->array[i];
list->size--;
return tmp;
}
else
printf("해당 원소(%d)는 존재하지 않습니다.\n",item);
}
else
printf("리스트가 비어 있습니다\n");
}
void print_list(ArrayListType list) {
for (int i = 0; i < list.size; i++)
printf("%d ", list.array[i]);
printf("size:%d\n", list.size);
}
int main() {
ArrayListType list;
init(&list);
printf("삽입:\n");
insert(&list, 10);
insert(&list, 9);
insert(&list, 8);
insert(&list, 11);
insert(&list, 12);
insert(&list, 16);
insert(&list, 7);
print_list(list);
printf("\n삭제:\n");
delete(&list, 10);
delete(&list, 9);
delete(&list, 8);
delete(&list, 11);
delete(&list, 100); // 리스트에 존재하지 않는 원소 삭제
print_list(list);
}

참고) 배열을 이용한 리스트 자료구조 소스: https://shacoding.com/2019/07/26/data-structure-list-by-array-c/