알고리즘을 구현하기 전에 알고리즘이 얼마나 효과적인지 분석하는 법을 이해해야 한다.
알고리즘을 구현할 때 빅오 표기법이 해당 알고리즘이 얼마나 효율적인지를 나타내기 때문에 빅오 표기법은 중요하다.
효율적인 방법을 고민한다는 것은 시간 복잡도를 고민한다는 것과 같은 말이다.
빅오 표기법은 알고리즘의 최악의 경우 복잡도를 측정하며 알고리즘의 효율성을 나타내는 표기법이다.
문제를 해결하는데 걸리는 시간과 입력의 관계를 가리킨다.
즉, 입력값에 따라 연산을 실행할 때, 연산 횟수에 비해 얼마만큼의 시간이 걸리는가를 의미한다.
시간복잡도를 고민한다는 것은 입력값이 커짐에 따라 증가하는 시간을 최소화한 알고리즘을 만들었다는 의미이기도 한다.
시간복잡도는 Big-o 표기법을 사용해 나타낼 수 있다.
출처 : 자바스크립트로하는 자료 구조와 알고리즘
*시간복잡도 순서 : 𝑂(1) < 𝑂(log n) < 𝑂(n) < 𝑂(n log n) < 𝑂(n²) < 𝑂(n³) < 𝑂(2ⁿ) < 𝑂(n!)
알고리즘 분석 시 가장 자주 등장하는 유형
표기법 | 명칭 |
---|---|
O(1) | 상수 |
O(n) | 선형 |
O(n²) | 2차 |
O(log₂ n) | 로그 |
O(n log₂ n) | 다형 로그 |
O(n^c) | 고차 |
O(2ⁿ) | 지수 |
알고리즘의 효율은 어떻게 측정할 수 있을까?
보통 CPU(소요 시간), 메모리, 디스크, 네트워크의 사용량을 생각할 수 있는데, 그중 O 표기법은 CPU 사용량을 대상으로 한다.
입력값이 증가하더라도 시간은 변하지 않는다. 따라서 O(1)을 상수 시간이라고 부른다.
입력값의 크기와 관계없이 즉시 출력값을 얻을 수 있다.
배열의 항목을 인덱스를 사용해 접근하는 경우를 예로 들 수 있다.
// 예제 1
function O_1(arr, index) {
return arr[index];
}
const arr = ['a', 'b', 'c', 'd', 'e'];
let index = 3;
console.log(O_1(arr, index)); // 'd'
// 예제 2
function increment(num) {
return num++;
}
console.log(increment(99)); // 100
선형 복잡도라고 부르며, 입력값의 증가도에 따라 시간도 동일한 비율로 증가하는 것을 의미한다.
// 예제 3
function sequentialSearch(array, item) {
for (let i = o; i < array.length; i++) {
if (item === array[i]) {
return i;
}
}
return -1;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const item = 1;
O(n²)은 2차 복잡도라고 부르며, 입력값이 증가함에 따라 시간이 n의 제곱수의 비율로 증가하는 것을 의미한다.
대표적으로 버블 정렬 알고리즘이 있다.
// 예제 4
function swap(array, index1, index2) {
let aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
function bubbleSort(array) {
let length = array.length;
for (let i = 0; i < length; i++) {
for (let j = 0; j < length - 1; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
bubbleSort(array);
* 단일 루프라면 O(n), 중첩 루프면 O(n²), 삼중 루프라면 복잡도는 O(n³)이 된다.
출처 : https://www.bigocheatsheet.com/
-참고