🎮 주제 : 삽입 정렬의 메커니즘과 유클리드 호제법의 재귀적 구현
태그 : #C++ #알고리즘 #삽입정렬 #최대공약수 #유클리드호제법 #재귀함수
📌 학습 요약
- 삽입 정렬(Insertion Sort) : 두 번째 원소부터 시작하여 앞쪽의 정렬된 부분과 비교하며 자신의 위치를 찾아 "삽입"하는 정렬 방식으로, 거의 정렬된 데이터에서 매우 효율적인 성능 발휘
- 데이터 이동(Shifting) : 값을 교환(Swap)하는 대신 적절한 자리가 나올 때까지 기존 원소들을 한 칸씩 뒤로 밀어내는(Shift) 과정을 통해 연산 횟수 최적화
- 최대공약수(GCD) : 두 수 이상의 공통된 약수 중 최대값을 구하는 원리를 파악하고, 약수와 서로소의 개념 정립
- 유클리드 호제법 : $x$를 $y$로 나눈 나머지 $r$이 있을 때, $GCD(x, y) = GCD(y, r)$이라는 성질을 이용해 재귀적으로 해를 구하는 알고리즘 습득
🛠 주요 코드 및 구현 상세
1. 삽입 정렬(Insertion Sort) 핵심 구현
// i는 현재 정렬할 'key'를 선택하고, j는 정렬된 왼쪽 구간을 탐색
for (int i = 1; i < size; i++) {
int key = list[i]; // 삽입할 대상 값 보관
int j = i - 1;
// key보다 큰 값들을 오른쪽으로 한 칸씩 밀어냄
while (j >= 0 && list[j] > key) {
list[j + 1] = list[j];
j--;
}
// 적절한 위치를 찾으면 보관했던 key를 삽입
list[j + 1] = key;
}
2. 유클리드 호제법 (재귀 함수)
int Max(int x, int y) {
int r = x % y;
// 나머지가 0이면 나누는 수인 y가 최대공약수
if (r == 0) return y;
// (작은 수, 나머지)로 다시 함수 호출
return Max(y, r);
}
✅ 주요 문법 및 개념 정리
개념 특징 주의 사항
| 삽입 정렬 | 최선의 경우 $O(n)$, 평균 $O(n^2)$ | 이미 정렬된 데이터에 매우 빠름 |
| 재귀 함수 | 자기 자신을 호출하여 문제를 분할함 | 종료 조건 누락 시 스택 오버플로우 발생 |
| 유클리드 호제법 | 나눗셈만으로 최대공약수를 빠르게 도출 | 큰 수를 $x$, 작은 수를 $y$로 두는 것이 기본 |
| Shifting | list[j + 1] = list[j] | key를 덮어쓰지 않도록 미리 백업 필수 |
💡 알고리즘 인사이트 : 왜 j + 1인가?
- while 루프가 끝나는 시점에 j는 key보다 작거나 같은 값의 인덱스를 가리키거나 1이 됩니다.
- 따라서 key가 들어갈 자리는 그 바로 오른쪽인 j + 1이 됩니다.
✨ 느낀 점
- 삽입 정렬에서 변수 j의 변화에 따라 배열의 원소들이 옆으로 밀려나는 과정을 시뮬레이션하며 반복문의 정밀한 제어법을 익힘
- 복잡할 수 있는 최대공약수 계산을 유클리드 호제법과 재귀 함수를 결합해 단 몇 줄로 해결하는 논리의 간결함에 감탄함
- 재귀 함수를 작성할 때 종료 조건(r == 0)의 설정이 프로그램의 생존을 결정짓는 핵심임을 다시금 확인함
- 단순히 암기하는 것이 아니라 key라는 임시 저장소와 while문의 종료 조건을 연결하여 사고하는 훈련의 중요성을 느낌
'SBS아카데미 > 게임프로그래밍' 카테고리의 다른 글
| [C++ - TIL] 분할 정복의 원리와 효율적인 알고리즘 설계 전략 (0) | 2025.08.19 |
|---|---|
| [C++ - TIL] 에라토스테네스의 체를 이용한 효율적인 소수 판별 구현 (0) | 2025.08.18 |
| [C++ - TIL] 선택 정렬 알고리즘의 메커니즘과 배열 조작의 기초 (0) | 2025.08.13 |
| [C++ - TIL] 알고리즘 성능 지표와 SFML 환경 설정의 이해 (0) | 2025.08.12 |
| [C++ - TIL] 원형 연결 리스트의 중복 데이터 제거 및 포인터 관리 (0) | 2025.08.07 |