배열과 연결 리스트의 차이: 읽기·삽입과 삭제·메모리 배치·캐시·시간 복잡도 비교
배열은 같은 타입의 요소를 메모리에 빈틈없이 연속해서 늘어놓고, 요소 번호(인덱스)로 위치를 계산해 어느 요소든 일정한 시간에 읽고 쓸 수 있는 자료 구조입니다. 연결 리스트는 각 요소가 값과 다음 요소의 위치를 가리키는 포인터를 가지고, 그것을 따라가며 이어지는 자료 구조로, 요소를 메모리의 떨어진 곳에 둘 수 있습니다. 배열은 읽기가 빠른 대신, 중간에 삽입하거나 삭제할 때는 뒤의 요소를 옮겨야 합니다. 연결 리스트는 위치를 알고 있으면 포인터를 바꾸는 것만으로 삽입과 삭제를 할 수 있는 대신, i번째 요소를 읽으려면 처음부터 차례로 따라가야 합니다. 번호로 읽는 일이 많으면 배열, 정해진 위치에서의 삽입과 삭제가 많으면 연결 리스트라는 것이 기본적인 선택 기준입니다.
| 비교 항목 | 배열 | 연결 리스트 |
|---|---|---|
| 메모리상의 배치 | 요소가 연속된 영역에 빈틈없이 늘어선다 | 요소는 흩어진 곳에 놓이고 포인터로 이어진다 |
| i번째 요소 읽기 | O(1). 시작 주소 + i × 요소 크기로 위치를 계산할 수 있다 | O(n). 처음부터 포인터를 i번 따라간다 |
| 값 탐색 | 정렬되어 있지 않으면 O(n)의 선형 탐색. 정렬되어 있으면 이진 탐색으로 O(log n) | 정렬되어 있어도 O(n). 중간 요소로 한 번에 이동할 수 없으므로 이진 탐색을 쓸 수 없다 |
| 중간 삽입·삭제 | O(n). 뒤의 요소를 하나씩 옮긴다 | 삽입할 위치(바로 앞 요소)를 알고 있으면 O(1). 포인터를 바꾸기만 하면 된다 |
| 끝에 추가 | 빈 공간이 있으면 O(1). 가변 길이 배열에서 용량을 2배씩 늘리는 방식은 가끔 전체를 복사하지만, 평균하면 O(1)(분할 상환) | 끝 요소를 가리키는 포인터를 가지고 있으면 O(1) |
| 크기 변경 | 고정 길이 배열은 만들 때 크기를 정한다. 늘리려면 새 영역을 확보하고 복사한다 | 요소마다 영역을 확보하므로 필요한 만큼만 늘릴 수 있다 |
| 사용하는 메모리 | 요소의 몫만으로 충분하다(가변 길이 배열은 예비 용량을 가진다) | 요소마다 포인터만큼 추가로 든다(이중 연결 리스트라면 2개분) |
| 캐시 효율 | 좋다. 연속해서 늘어서 있으므로 차례로 읽으면 캐시와 프리페치가 잘 작동한다 | 나쁘다. 요소가 흩어지기 쉬워, 같은 O(n) 순회라도 배열보다 크게 느려질 수 있다 |
| 주요 용도 | 인덱스로 읽고 쓰는 표, 행렬과 이미지, 정렬이나 이진 탐색의 대상, 스택과 큐의 구현 | 삽입과 삭제가 잦은 열, 해시 테이블의 체이닝, 빈 영역 관리 |
수치는 대략적인 자릿수 기준이며, 공정 세대와 제품에 따라 달라져요.