반응형
정렬 알고리즘 (Sorting Algorithms)
정렬 알고리즘은 주어진 데이터를 특정 순서대로 정렬하는 알고리즘입니다. 정렬은 컴퓨터 과학에서 매우 중요한 개념으로, 데이터의 효율적인 검색 및 정렬된 데이터를 필요로 하는 다양한 알고리즘의 기반이 됩니다.
정렬 알고리즘의 종류:
- 버블 정렬 (Bubble Sort)
- 선택 정렬 (Selection Sort)
- 삽입 정렬 (Insertion Sort)
- 합병 정렬 (Merge Sort)
- 퀵 정렬 (Quick Sort)
- 힙 정렬 (Heap Sort)
- 기수 정렬 (Radix Sort)
- 계수 정렬 (Counting Sort)
정렬 알고리즘 비교
비교 기준:
- 시간 복잡도 (Time Complexity): 알고리즘이 실행되는 데 걸리는 시간의 척도입니다.
- 공간 복잡도 (Space Complexity): 알고리즘이 사용하는 메모리의 양입니다.
- 안정성 (Stability): 동일한 키를 가진 요소들의 상대적인 순서를 유지하는 특성입니다.
- 내부 정렬 (In-place): 추가적인 메모리를 사용하지 않고 정렬하는 특성입니다.
버블 정렬 (Bubble Sort)
버블 정렬은 가장 간단한 정렬 알고리즘 중 하나로, 인접한 두 요소를 비교하여 정렬합니다. 시간 복잡도는 (O(n^2))입니다.
버블 정렬 구현
#include <iostream>
#include <vector>
// 버블 정렬 함수
void bubbleSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]); // 인접한 두 요소 교환
}
}
}
}
int main() {
std::vector<int> arr = {64, 34, 25, 12, 22, 11, 90};
std::cout << "정렬 전 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
bubbleSort(arr);
std::cout << "정렬 후 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
선택 정렬 (Selection Sort)
선택 정렬은 리스트에서 가장 작은 요소를 찾아 첫 번째 위치와 교환하는 과정을 반복합니다. 시간 복잡도는 (O(n^2))입니다.
선택 정렬 구현
#include <iostream>
#include <vector>
// 선택 정렬 함수
void selectionSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; ++i) {
int minIndex = i;
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[minIndex]) {
minIndex = j; // 가장 작은 요소의 인덱스 찾기
}
}
std::swap(arr[i], arr[minIndex]); // 가장 작은 요소를 첫 번째 위치로 이동
}
}
int main() {
std::vector<int> arr = {64, 25, 12, 22, 11};
std::cout << "정렬 전 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
selectionSort(arr);
std::cout << "정렬 후 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
삽입 정렬 (Insertion Sort)
삽입 정렬은 배열의 요소를 하나씩 정렬된 부분에 삽입하는 방식으로 동작합니다. 시간 복잡도는 (O(n^2))입니다.
삽입 정렬 구현
#include <iostream>
#include <vector>
// 삽입 정렬 함수
void insertionSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j]; // 정렬된 부분에서 키보다 큰 요소 이동
--j;
}
arr[j + 1] = key; // 키를 정렬된 부분에 삽입
}
}
int main() {
std::vector<int> arr = {12, 11, 13, 5, 6};
std::cout << "정렬 전 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
insertionSort(arr);
std::cout << "정렬 후 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
합병 정렬 (Merge Sort)
합병 정렬은 분할 정복(Divide and Conquer) 기법을 사용하는 효율적인 정렬 알고리즘입니다. 배열을 반으로 나누어 각각을 정렬한 후 합병합니다. 시간 복잡도는 (O(n \log n))입니다.
합병 정렬 구현
#include <iostream>
#include <vector>
// 병합 함수
void merge(std::vector<int>& arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
std::vector<int> L(n1);
std::vector<int> R(n2);
for (int i = 0; i < n1; ++i) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; ++j) {
R[j] = arr[mid + 1 + j];
}
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
++i;
} else {
arr[k] = R[j];
++j;
}
++k;
}
while (i < n1) {
arr[k] = L[i];
++i;
++k;
}
while (j < n2) {
arr[k] = R[j];
++j;
++k;
}
}
// 합병 정렬 함수
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
int main() {
std::vector<int> arr = {12, 11, 13, 5, 6, 7};
std::cout << "정렬 전 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
mergeSort(arr, 0, arr.size() - 1);
std::cout << "정렬 후 배열: ";
for (int value : arr) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
설명
- 버블 정렬 (Bubble Sort):
- 인접한 두 요소를 비교하여 정렬합니다.
- 시간 복잡도: (O(n^2))
- 선택 정렬 (Selection Sort):
- 리스트에서 가장 작은 요소를 찾아 첫 번째 위치와 교환하는 과정을 반복합니다.
- 시간 복잡도: (O(n^2))
- 삽입 정렬 (Insertion Sort):
- 배열의 요소를 하나씩 정렬된 부분에 삽입합니다.
- 시간 복잡도: (O(n^2))
- 합병 정렬 (Merge Sort):
- 분할 정복 기법을 사용하여 배열을 반으로 나누어 각각을 정렬한 후 합병합니다.
- 시간 복잡도: (O(n \log n))
이제 기본적인 정렬 알고리즘의 개념과 구현 방법을 이해했습니다. 다음 단계로 넘어가며, 더 복잡한 정렬 알고리즘과 다양한 알고리즘을 학습해보겠습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 16: 버블 정렬과 선택 정렬"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++로 배우는 알고리즘과 자료구조 시리즈' 카테고리의 다른 글
[C++로 배우는 알고리즘과 자료구조] Day 17: 삽입 정렬과 쉘 정렬 (0) | 2024.08.01 |
---|---|
[C++로 배우는 알고리즘과 자료구조 ] Day 14: 해시 함수와 충돌 해결 기법 (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조] Day 12: 그래프 표현 방법 (인접 리스트, 인접 행렬) (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조] Day 13: 이진 힙과 힙 정렬 (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조 ] Day 10: 트라이 (Trie) (0) | 2024.08.01 |