<버블 정렬 구현>

[BubbleSort.c]

/*
* 알고리즘 - 버블 정렬(Bubble Sort)
* 파일명: BubbleSort.c
* 파일 버전: 0.1
* 작성자: Sevenshards
* 작성 일자: 2023-11-26
* 이전 버전 작성 일자:
* 버전 내용: 간단한 버블 정렬 구현
* 이전 버전 내용:
*/

#include <stdio.h>

void BubbleSort(int arr[], int n)
{
	int i, j; // 반복문에 쓰일 변수 i, j
	int temp; // 변수 swap에 사용할 임시 변수

	for (i = 0; i < n - 1; i++) // 데이터가 n개라면 n-1만큼의 반복을 수행하여 정렬 진행
	{
		for (j = 0; j < (n - i) - 1; j++) // 교환이 이뤄지는 부분. 정렬되어 가면서 비교할 인덱스의 수가 줄어가므로 조건식은 j<(n-i)-1
		{
			if (arr[j] > arr[j + 1])
			{
				// 데이터 정렬
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

int main()
{
	int arr[4] = { 3, 2, 1, 4 };
	int i;

	BubbleSort(arr, sizeof(arr) / sizeof(int));

	for (i = 0; i < 4; i++)
		printf("%d ", arr[i]);

	printf("\n");
	
	return 0;
}

 

[정렬 알고리즘을 배우기에 앞서]

우선순위 큐까지 학습하고 나서 자료구조에서 알고리즘으로 넘어가게 되었다.

자료구조를 공부하면서 갑자기 왜 알고리즘, 그것도 정렬에 관련된 것을 배우는가?

예전에는 이걸 공부하면서도 느닷없이 왜 이렇게 가는지에 대해서는 깊이 생각하질 않았었다.

그냥 가르쳐주니까 맹목적으로 배우기만 했었지, 그 이유를 생각하지는 않았던 것이다.

정렬 알고리즘을 배우는 이유는 자료구조에서의 '탐색'을 이해하기 위해서 배우는 것이다.

자료구조의 3대 연산[삽입, 삭제, 탐색(조회)]에 있다.

자료구조마다 어떻게 탐색하고 데이터를 조회하느냐는 성능과 연관이 있다.

그리고 여기서 탐색을 할 때 '정렬이 된 대상'을 탐색하게 된다.

그래서 탐색을 배우기 이전에 정렬이 선행되는 이유인 것이다.

 

[버블 정렬의 이해]

가장 단순한 정렬 알고리즘인 버블 정렬.
C에서도, C++에서도, 어지간한 언어들에서는 한 번씩은 봤던 정렬 알고리즘이다.
버블 정렬은 인접한 두 개의 데이터를 비교해가면서 정렬을 진행하는 방식이다.
그리고 정렬 순서 상 바뀌어야 하는 경우에는 두 데이터의 위치를 바꿔나가게 된다.
정렬의 기준을 토대로 우선순위가 가장 낮은, 제일 큰 값을 맨 뒤로 보내는 것이 해당 정렬의 특징이다.
버블 정렬인 이유는 앞에서부터 비교하고 교환하는 일련의 과정이 거품이 일어나는 모습에 같아서 그렇다고 한다.

[성능 평가]

정렬 알고리즘의 성능 평가는 두 가지를 근거로 평가를 하게 된다.

1) 비교의 횟수 → 비교 연산이 얼마나 수행되는가 → 대부분 빅-오 결정은 여기서
2) 이동의 횟수 → 위치의 변경을 위한 데이터의 이동 횟수 → 빅-오의 복잡도를 갖는 알고리즘간의 세밀한 비교 가능

버블 정렬의 경우, 위에 있는 for문이 중첩된 부분에 의해 비교연산이 수행된다.
위의 예시는 4개의 데이터를 총 3단계에 걸쳐서 정렬했다.
그렇다면 $n$개의 데이터라면? $n-1$단계에 거쳐서 정렬을 수행한다.
버블 정렬에서의 데이터 갯수가 $n$개일 때, 진행이 되는 비교의 횟수는 다음과 같아진다.

$(n-1) + (n-2) + … + 2 + 1$

이는 등차수열의 합으로 표현할 수 있으며, 다음과 같이 계산된다.

$$
\sum_{i=1}^{n-1}i = \frac{n(n-1)}{2} = \frac{n^2-n}{2}
$$

그래서 버블 정렬의 비교 연산에 대한 빅-오는 최악의 경우나 최선의 경우 구분 없이 $O(n^2)$이다.
그리고 데이터 이동 횟수는 데이터가 이미 정렬이 다 되어있는 상태라면 데이터의 이동(교환)이 한 번도 발생하지 않는다.
하지만 최악의 경우에는 비교연산 횟수와 이동의 횟수가 일치하므로 $O(n^2)$이다.
엄밀히 따지면 3배 더 많지만, 빅-오를 판단하는 과정에서는 이를 고려하지 않는다.

sevenshards