정렬은 컴퓨터 과학에서 필수적인 작업입니다. 요소 컬렉션을 정렬하는 기본 알고리즘 중 하나는 버블 정렬입니다. 가장 효율적이지는 않지만 단순성과 이해 용이성으로 인해 정렬 알고리즘을 배우는 모든 사람에게 기본적인 출발점이 됩니다.
이 블로그 게시물에서는 버블 정렬 알고리즘에 대해 자세히 알아보고 C#에서 실용적인 구현을 제공합니다.
버블 정렬 이해하기
버블 정렬은 간단한 비교 기반 알고리즘입니다. 알고리즘은 데이터 세트의 시작 부분에서 시작하여 인접한 항목의 각 쌍을 차례로 비교하고 순서가 잘못된 경우 교환하고 교환 없이 목록을 통과할 때까지 이 프로세스를 계속합니다.
버블 정렬 실행
간단한 정렬되지 않은 배열을 살펴보겠습니다: [5, 3, 8, 4, 2]
- 첫 번째 패스에서는 첫 번째 쌍(5,3)에서 시작합니다. 5 > 3이므로 [3, 5, 8, 4, 2]로 바꿉니다.
- 다음으로 두 번째 쌍(5,8)을 비교합니다. 순서대로 되어 있으므로 교환할 필요가 없습니다.
- 다음 쌍(8,4)의 순서가 잘못되었으므로 [3, 5, 4, 8, 2]로 바꿉니다.
- 마지막 쌍(8,2)도 순서가 맞지 않습니다. 다시 교체합니다: [3, 5, 4, 2, 8]
- 이제 첫 번째 패스가 완료되었습니다. 가장 큰 숫자인 8은 배열의 끝에서 올바른 위치로 '버블링'되었습니다.
- 더 이상 스왑이 필요하지 않을 때까지 나머지 요소에 대해 이 프로세스를 반복합니다.
버블 정렬 구현하기
다음은 C#에서 버블 정렬을 간단하게 구현한 것입니다.
public void BubbleSort(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
// Swap arr[j] and arr[j + 1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
위의 코드에서:
- 외부 루프 i는 배열의 시작에서 두 번째 마지막 요소까지 실행됩니다(우리는 항상 쌍을 비교하므로 자체적으로 마지막 요소를 고려할 필요가 없습니다). 이 루프는 알고리즘이 통과하는 횟수를 나타냅니다.
- 내부 루프 'j'도 배열의 처음부터 시작하지만 배열의 끝 부분이 이미 정렬되어 있기 때문에 각 패스에서 더 일찍 멈춥니다.
- 내부 루프 내에서 알고리즘은 각 요소 쌍을 확인하고 순서가 잘못된 경우 교체합니다.
시간 복잡도
버블 정렬의 최악의 경우와 평균 시간 복잡도는 O(n^2)입니다. 여기서 n은 정렬되는 항목의 수입니다. 가능한 모든 스왑이 이루어지기 때문에 어레이가 역순으로 정렬될 때 최악의 시나리오가 발생합니다. 최상의 시나리오(이미 정렬된 배열)는 여전히 n-1이 요소를 통과하게 하지만 스왑은 수행하지 않습니다. 따라서 최적의 시간 복잡도는 O(n)입니다.
결론
버블 정렬은 단순하고 직관적인 정렬 알고리즘이지만 더 큰 데이터 세트에는 비효율적입니다. 보다 복잡한 정렬 알고리즘을 이해하기 위한 기초를 구축하기 위한 교육 목적으로 자주 사용됩니다. 이 블로그에서 제공하는 C# 구현을 통해 이 정렬 알고리즘이 작동하는 방식을 실질적으로 이해할 수 있습니다. 정렬 알고리즘을 더 깊이 파고들수록 퀵 정렬, 병합 정렬, 힙 정렬 등과 같은 복잡하지만 더 효율적인 정렬 기술을 접하게 될 것입니다.
'C# > Algorithm' 카테고리의 다른 글
최소 신장 트리 : Kruskal Algorithm (0) | 2023.07.11 |
---|---|
선택 정렬 : Selection sort (0) | 2023.07.11 |
무차별 대입 알고리즘 : Brute Force (0) | 2023.07.10 |
최단 경로 알고리즘 : Dijkstra (0) | 2023.07.10 |
Greedy Algorithm: 간단하면서도 효과적인 문제 해결 방법 (0) | 2023.07.09 |