티스토리 뷰
● 도입
- 앞으로 몇 개의 글에서 배열에 무작위로 섞인 숫자를 정렬하는 방법에 대해 알아볼 것이다.
- 이번 글에서는 여러개의 정렬 알고리즘 중 Bubble Sort에 대해 알아볼 것이다.
- Bubble Sort는 가장 쉬운 정렬 알고리즘 중 하나이다.
● 개념
- Bubble Sort는 앞에 있는 숫자와 옆에 있는 숫자의 크기를 비교해 자리를 바꾸는 알고리즘이다.
[4, 2, 3, 1]
- 위와 같이 숫자가 무작위로 들어있는 배열이 있다고 했을 때 아래와 같은 작업이 일어난다.
1). 가장 앞에 있는 숫자 4와 그 옆에 있는 숫자 2의 크기를 비교한다.
2). (4 > 2)이므로 4와 2의 자리를 바꾼다. → [2, 4, 3, 1]
3). 두 번째 숫자 4와 그 옆에 있는 숫자 3의 크기를 비교한다.
4). (4 > 3)이므로 4와 3의 자리를 바꾼다. → [2, 3, 4, 1]
5). 세 번째 숫자 4와 그 옆에 있는 숫자 1의 크기를 비교한다.
6). (4 > 1)이므로 4와 1의 자리를 바꾼다. → [2, 3, 1, 4]
------------------------------------------------------------------------------------------------------------------------------------------------------
7). 다시 배열의 (index = 0)부터 위에서 했던 작업을 동일하게 진행한다.
단, 배열의 마지막 원소에는 이미 가장 큰 숫자가 위치했기에 작업 범위에서 제외한다.
8). 가장 앞에 있는 숫자 2와 그 옆에 있는 숫자 3의 크기를 비교한다.
9). (2 < 3)이므로 2와 3의 자리를 바꾸지 않는다. → [2, 3, 1, 4]
10). 두 번째 숫자 3과 그 옆에 있는 숫자 1의 크기를 비교한다.
11). (3 > 1)이므로 3과 1의 자리를 바꾼다. → [2, 1, 3, 4]
12). 배열의 마지막 원소인 4는 작업 범위에서 제외됐기에 3과 4의 크기는 비교하지 않는다.
------------------------------------------------------------------------------------------------------------------------------------------------------
13). 다시 배열의 (index = 0)부터 위에서 했던 작업을 동일하게 진행한다.
단, 배열의 마지막 원소(4)와 그 이전 원소(3)는 이미 큰 숫자가 차례대로 위치했기에 작업 범위에서 제외한다.
14). 가장 앞에 있는 숫자 2와 그 옆에 있는 숫자 1의 크기를 비교한다.
15). (2 > 1)이므로 2와 1의 자리를 바꾼다. → [1, 2, 3, 4]
16). 배열의 마지막 원소인 4와 그 이전 원소인 3은 작업 범위에서 제외됐기에 더 이상 크기를 비교하지 않는다.
------------------------------------------------------------------------------------------------------------------------------------------------------
17). 다시 배열의 (index = 0)부터 위에서 했던 작업을 동일하게 진행한다.
하지만 남은 원소(1)가 하나이므로 더 이상 정렬 작업을 수행할 필요가 없다.
정렬 끝!!!!
- Bubble Sort는 이와 같이 옆의 데이터와 크기를 비교해서 자리를 바꾸는 알고리즘이다.
● 실습
function bubbleSort(arr) {
for (let i = 0; i < (arr.length - 1); i++) { // 배열을 순회할 for문
for (let j = 0; j < (arr.length - i - 1); j++) { // 각 원소의 크기를 비교하고 자리를 바꿀 for문
if(arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
let arr = [4, 2, 3, 1];
console.log("======= 정렬 전1 =======");
console.log(arr);
console.log("======= 정렬 후1 =======");
bubbleSort(arr);
console.log(arr);
let arr2 = [234, 23, 87, 34, 99, 103];
console.log("======= 정렬 전2 =======");
console.log(arr2);
console.log("======= 정렬 후2 =======");
bubbleSort(arr2);
console.log(arr2);
(arr.length - 1)
- 배열의 개수가 n개라면 자리 교체는 n-1번을 해야 하므로 (arr.length - 1)로 범위 설정
ex)
배열의 개수가 4개라면 자리 교체는 3번을 해야 하므로 (4 -1)로 범위 설정
==========================================================================================
(arr.length - i - 1)
- 배열의 첫번째 원소부터 정렬이 된 원소의 이전 원소보다 하나 이전의 원소까지 순회해야한다.
-i --> 정렬이 된 원소(정렬이 완료된 개수만큼을 i로 빼줘서 범위를 줄여준다.)
-1 --> 정렬이 된 원소의 이전 원소보다 하나 이전의 원소
ex) [3, 2, 1, 4]
- 가장 큰 수인 4가 정렬된 상태라면 (i = 1)이고
- 정렬이 된 원소(4)의 이전 원소(1)보다 하나 이전의 원소(2)까지 순회해야한다.
- 즉, {첫 번째 원소(3) ~ 두 번째 원소(2)}까지 두 번만 순회하면 된다.
- 배열의 길이(4)에서 i 값과 1을 빼면 2번만 반복된다.(4 - i - 1 = 4 - 1 - 1)
● 정리
- Bubble Sort는 구현은 쉽지만 성능이 좋다고 할 수는 없다. 이중 반복문을 사용하는 것 자체에서부터 싹수를 알 수 있다.
- Big-O로 Bubble Sort의 성능을 알아보자
- 길이가 n인 배열에서 반복문을 한 번씩 돌때마다 마지막 원소가 정렬되는 것을 알 수 있었다.
- 즉, 바깥쪽 for 문이 반복될 때마다 정렬되지 않은 원소 중 가장 큰 원소가 정렬되고 안쪽 for문은 반복 횟수가 점점 줄어든다.(원소가 하나씩 정렬될수록 정렬되지 않은 원소의 개수는 줄어들기 때문)
- 이렇게 원소가 1개만 남을때까지 반복하는데 이를 수학식으로 풀어보면 다음과 같다.
- 즉, 등차수열의 합과 같다.
- 시간복잡도에서 Big-O는 가장 높은 차수를 선택하고 자연수는 버려야 하기에 결론적으로 Big-O는 O(n^2)가 된다.
cf) 여기에서 자연수는 (1/2) 이다.
- 아래의 그림에서 볼 수 있듯이 O(n^2)은 성능이 좋지 않다. 그렇기에 성능이 중요한 시스템에서 Bubble Sort는 적절치 않을 수 있다.
- 참고로 이렇게 수학적으로 계산하는게 힘들면 "핵심 로직에서 for문 2개가 중첩되니까 대충 O(n^2) 구나"라고
생각해도 된다.
- Big-O는 정확도보다는 데이터가 증가할 때 계산이 늘어나는 척도만 보는 용도이기에 위와 같이 생각해도 무리는 없다.
cf)
2023.01.22 - [자료구조 및 알고리즘] - #2 시간복잡도(좋은 알고리즘?) / 최악의 경우는 Big-O
#2 시간복잡도(좋은 알고리즘?) / 최악의 경우는 Big-O
- 이전 글에서 자료구조에 따라 알고리즘이 달라지며 동일한 자료구조일지라도 구현할 수 있는 알고리즘은 천차만별이라는 것을 배웠다. - 떠오르는 수 많은 알고리즘 중 가장 정확하고 효율적
radderveloper.tistory.com
'CS > 자료구조 및 알고리즘' 카테고리의 다른 글
#11 삽입정렬(Insertion Sort) (0) | 2023.03.07 |
---|---|
#10 선택정렬(Selection sort) (0) | 2023.03.04 |
#8 해시테이블 - 개념(해시, 해시 함수) / ChatGPT 사용해봄 (1) | 2023.02.20 |
#7 큐(Queue) - 개념(FIFO : First In First Out) (0) | 2023.02.05 |
#6 Stack(스택) - 개념(FILO : First In Last Out) (1) | 2023.02.02 |
- Total
- Today
- Yesterday
- Advanced Stream
- MySQL
- 운영체제
- Phaser3
- OS
- 알고리즘
- node.js
- java
- Phaser
- git
- Spring Boot
- nosql
- 프로그래머스
- MongoDB
- jpa
- SQL
- 프로세스
- 메모리
- Stream
- DART
- db
- 자료구조
- API
- 빅데이터
- Java8
- 코딩테스트
- 코테
- SpringBoot
- spring
- 빅데이터 분석기사
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |