버블 정렬 (Bubble Sort)
💡 버블정렬 함수
먼저 알고리즘을 알고있지만 복붙이나 복습을 위해 찾아온 사람들을 위해 코드를 먼저 보여주겠다.
처음 보는거라면 꼭 아래로 내려가 이해해보도록 하자.
파이썬 (Python)
-
오름차순 (Bubble Sort - Ascending)
def bubbleSort_ASC(arr):
n = len(arr)
for i in range(n-1, -1, -1):
for j in range(0, i):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
-
내림차순 (Bubble Sort - Descending)
def bubbleSort_DESC(arr):
n = len(arr)
for i in range(n):
for j in range(n-1, i, -1):
if arr[j] > arr[j-1]:
arr[j], arr[j-1] = arr[j-1], arr[j]
return arr
자바 (Java)
-
오름차순 (Bubble Sort - Ascending)
public static void bubblesort_ASC(int[] arr) {
int temp = 0;
for(int i=0;i<arr.length;i++) {
for(int j=0; j < arr.length - i - 1 ; j++) {
if(arr[j]>arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
-
내림차순 (Bubble Sort - Descending)
public static void bubblesort_DESC(int[] arr) { int temp = 0; for(int i=0;i<arr.length;i++) { for(int j=0; j < arr.length - i - 1 ; j++) { if(arr[j]<arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } }
💡 버블정렬 (Bubble Sort) ?
버블 정렬은 원소를 정렬할 때 사용하며, 원소가 거품처럼 올라오는 것처럼 보여 버블 정렬이라는 이름이 붙여졌다.
💡 알고리즘 이해
가장 큰 수부터 차례대로 맨 뒤로 이동시켜 고정한다고 생각하면 쉽다.
각 단계에서 일어나는 일
다음 원소와 비교했을때, 지금의 원소가 더 크다면 순서를 바꾼다.
현재 원소와 다음 원소 비교 | 3 | 2 | 5 | 4 | 1 |
---|---|---|---|---|---|
arr[j]>arr[j+1] | 2 | 3 | 5 | 4 | 1 |
arr[j]<=arr[j+1] (변경 X) | 2 | 3 | 5 | 4 | 1 |
arr[j]>arr[j+1] | 2 | 3 | 4 | 5 | 1 |
arr[j]>arr[j+1] | 2 | 3 | 4 | 1 | 5 |
한 단계마다 가장 큰 수가 제일 뒤로 가게 된다.
모든 단계에서 일어나는 일
각 단계에서 정해진 가장 큰 수를 고정하고 그 앞부분에서 단계를 또 시작한다.
정렬 전 | 5 | 2 | 3 | 4 | 1 |
---|---|---|---|---|---|
1단계 | 2 | 3 | 4 | 1 | 5 |
2단계 | 2 | 3 | 1 | 4 | 5 |
3단계 | 2 | 1 | 3 | 4 | 5 |
4단계 | 1 | 2 | 3 | 4 | 5 |
💡 코드 이해
먼저, 배열의 두 원소를 바꾸는 함수부터 만들어보자.
다음 함수는 int타입 배열의 i번째 값과 j번째 값을 바꾸는 함수이다.
public static void swap (int[] arr, int i, int j) {
int temp = arr[i]; // temp에 i번째 값 저장
arr[i]=arr[j]; // i번째에 j번째 값 저장
arr[j]=temp; // j번째 값에 저장했던 원래의 i번째 값 넣기
}
미리 만들었던 swap 함수
를 사용하여 bubblesort 함수
를 만들어보자.
public static void bubblesort(int[] arr) {
for(int i=0;i<arr.length;i++) { // 단계를 i번 반복
for(int j=0; j < arr.length - i - 1 ; j++) { // 고정된 것을 제외하고 반복
if(arr[j]>arr[j+1]) { //현재 원소가 다음 원소보다 크면
swap(arr,j,j+1); //다음 원소와 바꾼다.
}
}
}
}
하지만 우리는 똑똑하니까 한번에 해보자.
두 함수를 합치면 다음과 같다.
public static void bubblesort(int[] arr) {
for(int i=0;i<arr.length;i++) {
for(int j=0; j < arr.length - i - 1 ; j++) {
if(arr[j]>arr[j+1]) { //오름차순일 경우 부호를 반대로 해주면 된다.
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
💡 코드 테스트 - 백준 2750번: 수 정렬하기
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++) {
arr[i] = sc.nextInt();
}
sc.close();
bubblesort(arr);
for(int i=0;i<n;i++) {
System.out.println(arr[i]);
}
}
public static void bubblesort(int[] arr) {
for(int i=0;i<arr.length;i++) {
for(int j=0; j < arr.length - i - 1 ; j++) {
if(arr[j]>arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}
Output
1
2
3
4
5
💡 시간복잡도
시간 복잡도가 무엇인지 모른다면 이 글을 참고하자.
[알고리즘] 시간 복잡도 (Time Complexity)
이미 정렬이 되어있는지에 상관 없이 무조건 for문을 2번 돌면서 비교를 하기 때문에
버블 정렬의 시간 복잡도는 best, worst, average case 모두 O(n^2)
이다.
💡 정리
장점
- 구현이 아주 간단하다.
- 알고리즘을 이해하기 쉽다.
단점
- 하나의 원소를 옮기는데 여러번 교환해야 하는 일이 발생한다.
- 이미 옳은 위치에 정렬되어있는 상태의 요소도 교환되는 일이 많다.
- 정렬 알고리즘 중에서 가장 느리고 효율성이 떨어진다.
💡 결론
버블정렬 알고리즘은 처음 알고리즘을 공부하기엔 좋지만 너무 비효율적이기 때문에 쓸 일이 없다.