BioPlayground

🧬
목록으로

배열 vs 연결 리스트

배열과 연결 리스트가 메모리에서 어떻게 다른지, 언제 어떤 것을 써야 하는지 이해합니다.

입문
|
7
|
검증 완료 (2026-07)
진행률0/6 (0%)

배열 vs 연결 리스트

이 토픽을 마치면

배열과 연결 리스트의 메모리 구조 차이를 설명할 수 있고, 상황에 따라 어떤 것을 선택해야 하는지 판단할 수 있습니다.


배열 — 연속된 메모리

배열(Array)은 데이터를 메모리에 나란히 저장합니다.

text
메모리 주소:  100  104  108  112  116
            +----+----+----+----+----+
값:         | 10 | 20 | 30 | 40 | 50 |
            +----+----+----+----+----+
인덱스:       0    1    2    3    4

장점은 인덱스로 즉시 접근 가능합니다.

python
arr = [10, 20, 30, 40, 50]
print(arr[3]) # 40 — 즉시 접근 (O(1))

"3번째 칸"이라고 하면 시작 주소 + (3 × 크기) = 바로 그 위치. 몇 개가 있든 한 번에 찾습니다.

배열의 약점: 삽입과 삭제

text
[10, 20, 30, 40, 50]에서 인덱스 1에 15를 삽입하려면?

1단계: 20, 30, 40, 50을 모두 한 칸씩 뒤로 밀기
2단계: 빈 자리에 15 넣기

[10, 15, 20, 30, 40, 50]

데이터가 100만 개면, 맨 앞에 삽입할 때 100만 개를 전부 밀어야 합니다.


연결 리스트 — 흩어진 메모리

연결 리스트(Linked List)는 각 데이터가 다음 데이터의 위치를 기억합니다.

text
[10|→] → [20|→] → [30|→] → [40|→] → [50|∅]

각 노드 = 값 + 다음 노드의 주소(포인터)

메모리에 연속으로 있을 필요가 없습니다. 각 노드가 "다음은 어디야"를 알고 있으면 됩니다.

연결 리스트의 장점: 삽입과 삭제

text
[10|→] → [20|→] → [30|→]에서 20 뒤에 25 삽입:

1단계: 새 노드 [25|→] 생성
2단계: 20의 포인터를 25로, 25의 포인터를 30으로 변경

[10|→] → [20|→] → [25|→] → [30|→]

다른 노드를 밀 필요가 없습니다. 포인터 2개만 바꾸면 끝. O(1).

연결 리스트의 약점: 접근

python
# "3번째 값이 뭐야?"
# 배열: arr[3] → 즉시 (O(1))
# 연결 리스트: 처음부터 1→2→3 따라가야 함 (O(n))

인덱스가 없으므로 n번째 값을 찾으려면 처음부터 n번 따라가야 합니다.


비교 정리

연산배열연결 리스트
인덱스 접근O(1) 즉시O(n) 순회 필요
검색O(n) 순회O(n) 순회
맨 앞 삽입O(n) 전부 밀기O(1) 포인터 변경
맨 뒤 삽입O(1) 끝에 추가O(1) 꼬리 포인터 있으면
중간 삽입O(n) 밀기O(1) 포인터 변경
메모리연속 필요흩어져도 됨

선택 기준

상황추천
인덱스로 자주 접근배열
삽입/삭제가 빈번연결 리스트
크기가 자주 변함연결 리스트
메모리 효율 중요배열 (포인터 오버헤드 없음)
캐시 친화성 필요배열 (연속 메모리)

실무에서는 대부분 배열(Python의 list, JavaScript의 Array)을 씁니다. 현대 언어의 동적 배열은 크기 조절도 자동이고, CPU 캐시에 유리합니다. 연결 리스트는 특수한 상황(큐, 스택 구현, 대용량 삽입/삭제)에서 사용합니다.