Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions _algorithms/JS-자료구조/big-o-notation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
title: "Big O Notation - 시간복잡도와 공간복잡도"
excerpt: "자료구조, 알고리즘 강의내용 정리"
coverImage: "/assets/algorithms/JS-자료구조/cover.png"
date: "2026-03-16T10:00:00"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

게시글의 날짜가 2026-03-16으로 미래 시점으로 설정되어 있습니다. 의도된 설정이 아니라면 실제 작성일로 수정하는 것이 좋겠습니다. 미래 날짜는 포스트 정렬이나 표시에 예기치 않은 문제를 일으킬 수 있습니다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

게시물의 날짜가 미래 시점(2026-03-16)으로 설정되어 있습니다. 의도하신 설정이 아니라면 현재 날짜나 과거 날짜로 수정해야 게시물이 정상적으로 노출될 수 있습니다. 오타일 가능성이 있어 보여 확인을 요청드립니다.

ogImage:
url: "/assets/algorithms/JS-자료구조/cover.png"
---

> Colt Steele의 JavaScript Algorithms and Data Structures Masterclass 강의를 보고 정리한 글입니다.

 

## Big O Notation이란?

알고리즘의 성능을 **단일 숫자(레이블)** 로 일반화하는 방법.

- 코드의 효율성을 비교하는 공통 언어
- 입력값 n이 커질수록 알고리즘이 얼마나 느려지는지를 나타냄
- 정확한 연산 횟수보다 **전체적인 추세(트렌드)** 에 집중

 

---

## 시간복잡도 (Time Complexity)

### Big O 계산 규칙

**1. 상수는 무시한다**

```javascript
// O(2n) → O(n)
function printPairs(arr) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

함수 이름이 printPairs이지만, 실제로는 배열의 모든 요소를 두 번 출력하고 있습니다. 이는 쌍(pair)을 출력하는 동작(보통 O(n²) 복잡도)과 혼동을 줄 수 있습니다. 예를 들어 108라인의 printAllPairs 함수는 실제로 쌍을 출력합니다. 함수의 동작을 더 명확하게 나타내는 이름(예: printItemsTwice)으로 변경하는 것을 고려해 보세요.

Suggested change
function printPairs(arr) {
function printItemsTwice(arr) {

for (let i = 0; i < arr.length; i++) { // n번
console.log(arr[i]);
}
for (let j = 0; j < arr.length; j++) { // n번
console.log(arr[j]);
}
}
```

**2. 작은 항은 무시한다**

```javascript
// O(n² + n) → O(n²)
function example(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) { // n²번
console.log(i, j);
}
}
for (let k = 0; k < arr.length; k++) { // n번 (무시)
console.log(k);
}
}
```

&nbsp;

### Big O 복잡도 종류 (빠른 순서)

| 표기 | 이름 | 설명 |
|------|------|------|
| O(1) | 상수 | 입력 크기와 무관하게 항상 동일한 시간 |
| O(log n) | 로그 | 이진 탐색처럼 탐색 범위가 절반씩 줄어듦 |
| O(n) | 선형 | 입력 크기에 비례 |
| O(n log n) | 선형 로그 | 효율적인 정렬 알고리즘 (merge sort 등) |
| O(n²) | 이차 | 중첩 반복문 |
| O(2ⁿ) | 지수 | 피보나치 재귀 등 |
| O(n!) | 팩토리얼 | 순열 탐색 등 |

```javascript
O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ) < O(n!)
```

&nbsp;

### O(1) - 상수 시간

```javascript
function addUpTo(n) {
return (n * (n + 1)) / 2; // 연산이 3번 → 항상 O(1)
}
```

&nbsp;

### O(n) - 선형 시간

```javascript
function addUpTo(n) {
let total = 0;
for (let i = 1; i <= n; i++) { // n번 반복
total += i;
}
return total;
}
```

&nbsp;

### O(n²) - 이차 시간

```javascript
// 중첩 반복문 → O(n * n) = O(n²)
function printAllPairs(n) {
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
console.log(i, j);
}
}
}
```

&nbsp;

---

## 공간복잡도 (Space Complexity)

입력값이 커질수록 **추가로 필요한 메모리** 가 얼마나 증가하는지.

입력값 자체가 차지하는 **공간은 제외**한다.

&nbsp;

### 자바스크립트 공간복잡도 규칙

| 타입 | 공간 |
|------|------|
| boolean, number, undefined, null | O(1) |
| string | O(n) — 문자열 길이에 비례 |
| 배열 (Array) | O(n) — 배열 길이에 비례 |
| 객체 (Object) | O(n) — 키 개수에 비례 |

&nbsp;

### O(1) 공간복잡도 예시

```javascript
function sum(arr) {
let total = 0; // 숫자 변수 1개
for (let i = 0; i < arr.length; i++) { // 숫자 변수 1개
total += arr[i];
}
return total;
}
// 변수 2개만 사용 → 입력 크기와 무관 → O(1)
```

&nbsp;

### O(n) 공간복잡도 예시

```javascript
function double(arr) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(2 * arr[i]); // 입력 배열 크기만큼 새 배열 생성
}
return newArr;
}
// newArr의 크기 = arr의 크기 → O(n)
```

&nbsp;

---

## 배열(Array)의 성능

| 연산 | 복잡도 | 이유 |
|------|--------|------|
| 접근 arr[i] | O(1) | 인덱스로 직접 접근 |
| 탐색 (search) | O(n) | 전체를 순회해야 함 |
| 삽입 - 끝 push | O(1) | 맨 뒤에 추가 |
| 삽입 - 앞 unshift | O(n) | 기존 인덱스 전부 재정렬 |
| 삭제 - 끝 pop | O(1) | 맨 뒤 제거 |
| 삭제 - 앞 shift | O(n) | 기존 인덱스 전부 재정렬 |
| concat | O(n) | |
| slice | O(n) | |
| splice | O(n) | |
| sort | O(n log n) | |
| forEach / map / filter / reduce | O(n) | |
Comment on lines +182 to +186

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

배열 성능 표의 concat, slice, splice, sort, forEach / map / filter / reduce 연산에 대한 '이유' 항목이 비어있습니다. 각 연산의 복잡도에 대한 이유를 간략하게 추가하면 문서를 이해하는 데 더 도움이 될 것 같습니다. 예를 들어, concat은 '새 배열을 생성하여 요소를 복사하기 때문'과 같이 설명할 수 있습니다.

Comment on lines +182 to +186

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

배열 성능 표에서 일부 연산(concat, slice, splice, sort, forEach 등)에 대한 '이유' 항목이 비어있습니다. 독자의 이해를 돕기 위해 각 연산의 복잡도에 대한 이유를 간략하게 추가하는 것을 제안합니다.

Suggested change
| concat | O(n) | |
| slice | O(n) | |
| splice | O(n) | |
| sort | O(n log n) | |
| forEach / map / filter / reduce | O(n) | |
| concat | O(n) | 새 배열 생성 후 요소 복사 |
| slice | O(n) | 새 배열 생성 후 요소 복사 |
| splice | O(n) | 요소 제거/추가 후 인덱스 재정렬 |
| sort | O(n log n) | 효율적인 정렬 알고리즘 사용 (엔진마다 다름) |
| forEach / map / filter / reduce | O(n) | 모든 요소를 한 번씩 순회 |


> **핵심**: 배열의 앞쪽을 건드리는 연산(unshift, shift)은 O(n)이므로 되도록 피한다.

&nbsp;

---

## 객체(Object)의 성능

순서가 없는 키-값 구조. 순서가 필요 없을 때 대부분 최적의 선택.

| 연산 | 복잡도 |
|------|--------|
| 삽입 | O(1) |
| 삭제 | O(1) |
| 접근 | O(1) |
| 탐색 (값 검색) | O(n) |
| Object.keys() | O(n) |
| Object.values() | O(n) |
| Object.entries() | O(n) |
| hasOwnProperty | O(1) |
Comment on lines +198 to +207

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

객체 성능 표에는 '이유' 열이 없습니다. 배열 성능 표와 일관성을 맞추고, 각 연산의 시간 복잡도에 대한 이유를 설명하기 위해 '이유' 열을 추가하는 것을 고려해 보세요. 예를 들어, 삽입/삭제/접근이 O(1)인 이유는 '해시 함수를 통해 키에 직접 접근하기 때문'이라고 설명할 수 있습니다.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading