이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.22 09:15
배열은 프로그래밍에서 가장 기본적이고 널리 사용되는 자료 구조 중 하나이다. 같은 자료형의 데이터 요소들을 연속된 메모리 공간에 순차적으로 저장하는 방식으로 구성된다. 이는 여러 개의 유사한 데이터 항목을 효율적으로 관리하고 접근하기 위한 핵심적인 방법을 제공한다.
배열의 가장 큰 특징은 인덱스를 통한 빠른 임의 접근이 가능하다는 점이다. 각 요소는 0부터 시작하는 고유한 인덱스 번호를 가지며, 이를 통해 상수 시간(O(1)) 내에 특정 위치의 데이터를 직접 읽거나 수정할 수 있다. 이 연속적인 메모리 배치는 CPU 캐시 지역성을 높여 성능에 유리한 영향을 미치기도 한다.
배열은 주로 1차원 배열의 형태로 사용되지만, 2차원 배열이나 3차원 배열과 같은 다차원 배열로 확장되어 행렬이나 표 형태의 데이터를 표현하는 데에도 활용된다. 또한, 크기가 고정된 정적 배열 외에도 실행 중에 크기가 변할 수 있는 동적 배열도 널리 사용된다.
이 구조는 반복문과 결합하여 데이터를 순차적으로 처리하거나, 알고리즘에서 다른 복잡한 자료 구조를 구현하는 기초 블록으로써 그 가치를 발휘한다. 배열의 단순하면서도 강력한 특성은 거의 모든 프로그래밍 언어에서 핵심 기능으로 지원되는 이유이기도 하다.
배열은 프로그래밍에서 가장 기본적이고 널리 사용되는 자료 구조 중 하나이다. 동일한 자료형의 데이터 요소들을 연속된 메모리 공간에 순차적으로 저장하는 방식으로 정의된다. 이 연속적인 물리적 배치는 배열의 가장 핵심적인 특징이자 다른 구조와 구분되는 중요한 원리이다.
배열의 각 요소는 0부터 시작하는 고유한 인덱스를 가지며, 이 인덱스를 통해 특정 위치의 요소에 직접 접근할 수 있다. 이 접근 연산은 요소의 물리적 주소를 단순한 계산으로 즉시 얻을 수 있기 때문에 시간 복잡도가 O(1)로 매우 빠르다. 이러한 임의 접근의 효율성은 배열이 탐색이나 데이터 조회가 빈번한 작업에 유리한 이유가 된다.
배열의 크기는 일반적으로 생성 시점에 결정되며, 이후에는 변경하기 어렵다. 이러한 정적 특성은 메모리 사용을 예측 가능하게 하지만, 필요에 따라 크기를 유연하게 조절해야 하는 상황에서는 제약이 될 수 있다. 이 제약을 극복하기 위해 동적 배열과 같은 변형 구조가 개발되었다. 또한 배열은 모든 요소가 동일한 자료형을 가져야 하므로, 서로 다른 형태의 데이터를 하나의 배열에 저장하는 것은 불가능하다.
배열의 구조는 반복문과 결합하여 데이터를 일괄 처리하는 데 매우 효율적이다. 이는 다수의 유사한 데이터 항목을 관리하거나, 행렬 및 표 형태의 데이터를 표현하는 데 적합하게 만든다. 이러한 특성 덕분에 배열은 알고리즘 구현의 기초가 되며, 거의 모든 프로그래밍 언어에서 핵심적으로 지원된다.
배열은 메모리 상에서 연속된 공간에 요소를 배치하는 방식으로 표현된다. 이는 배열의 가장 근본적인 특성으로, 첫 번째 요소의 메모리 주소(기본 주소)와 각 요소의 자료형 크기, 그리고 인덱스를 이용해 특정 요소의 위치를 즉시 계산할 수 있게 한다. 예를 들어 정수형 배열에서 각 정수가 4바이트를 차지한다면, array[5]의 주소는 기본주소 + (5 * 4)와 같은 공식으로 쉽게 찾을 수 있다. 이 메모리 주소의 직접 계산이 배열이 임의 접근에 매우 효율적인 이유이다.
이러한 물리적 표현은 논리적 구조와 밀접하게 연결된다. 1차원 배열은 선형으로 나열된 데이터를 표현하는 데 적합하다. 2차원 배열은 일반적으로 행 우선 순서나 열 우선 순서 방식으로 메모리에 매핑되는데, 대부분의 언어는 행 우선 순서를 채택하여 첫 번째 행의 모든 요소를 먼저 저장한 후 다음 행의 요소를 저장하는 방식으로 표현한다. 이는 메모리의 선형적 특성을 다차원 구조에 맞게 해석한 것이다.
프로그래밍 언어에서 배열은 구문을 통해 추상화되어 표현된다. 대괄호([])를 사용하여 선언하고 인덱스를 지정하는 방식이 보편적이다. 내부적으로 컴파일러나 인터프리터는 이 추상화된 코드를 메모리의 연속된 할당 및 주소 계산 명령어로 변환한다. 또한, C 언어처럼 메모리 주소 연산과 배열을 밀접하게 연결하는 언어도 있는 반면, 자바나 파이썬의 리스트처럼 더 높은 수준의 추상화를 제공하여 개발자로부터 물리적 표현을 숨기는 경우도 있다.
1차원 배열은 가장 기본적인 배열 형태로, 같은 자료형의 데이터 요소들이 하나의 선형 순서로 나열되어 있다. 각 요소는 0부터 시작하는 고유한 인덱스를 가지며, 이 인덱스를 통해 특정 위치의 데이터에 직접 접근할 수 있다. 이는 배열의 가장 큰 장점인 임의 접근이 가능함을 의미하며, 접근 시간 복잡도는 O(1)이다. 배열은 선언 시 크기가 고정되는 경우가 많아 정적 배열이라고도 불린다.
1차원 배열은 메모리에 연속적으로 할당된다. 예를 들어 정수형 배열이 선언되면, 메모리 상에서 정수 크기만큼의 공간이 차례대로 배치되어 요소들이 저장된다. 이 연속적인 메모리 배치 덕분에 CPU 캐시 효율이 높아져 데이터를 빠르게 처리할 수 있다. 또한 반복문과 함께 사용될 때 매우 효율적이며, 다수의 유사한 데이터 항목을 관리하는 데 널리 쓰인다.
대부분의 프로그래밍 언어는 1차원 배열을 기본적으로 지원한다. C 언어에서는 int arr[10];과 같이 크기를 명시하여 선언하며, 자바나 C++ 등에서도 유사한 문법을 사용한다. 이러한 배열은 자료 구조의 기초를 이루며, 더 복잡한 다차원 배열이나 행렬을 이해하는 토대가 된다.
다차원 배열은 배열의 요소 자체가 또 다른 배열인 구조이다. 가장 흔한 형태는 2차원 배열로, 행과 열로 구성된 표나 행렬을 표현하는 데 사용된다. 예를 들어, 3행 2열의 2차원 배열은 세 개의 행 배열이 각각 두 개의 요소를 가지고 있는 형태로 생각할 수 있다. 이는 게임의 격자 맵, 스프레드시트의 셀, 디지털 이미지의 픽셀 데이터 등을 저장하는 데 적합하다.
2차원을 넘어 3차원, 4차원 배열도 가능하다. 3차원 배열은 큐브 형태로, 각 차원마다 인덱스를 필요로 한다. 이러한 다차원 배열은 과학 계산에서 3차원 공간 데이터를 다루거나, 머신러닝에서 다중 채널의 텐서를 표현할 때 활용된다. 대부분의 프로그래밍 언어에서 다차원 배열은 실제로는 '배열의 배열' 방식으로 구현되어 메모리에 저장된다.
다차원 배열의 요소에 접근하려면 각 차원에 해당하는 인덱스를 지정해야 한다. 예를 들어, 2차원 배열 arr[i][j]에서 i는 행 인덱스, j는 열 인덱스를 의미한다. 이 접근도 시간 복잡도 O(1)로 매우 빠르게 이루어진다. 그러나 배열 전체를 순회하려면 중첩된 반복문이 필요하며, 이는 데이터의 차원 수만큼 반복문의 깊이가 깊어짐을 의미한다.
다차원 배열은 메모리에 연속적으로 할당되기 때문에 캐시 지역성이 좋아 처리 속도가 빠른 장점이 있다. 하지만 배열의 크기가 각 차원마다 고정되어 있어, 런타임에 구조를 유연하게 변경하기는 어렵다는 단점도 있다. 이러한 경우에는 동적 배열을 요소로 사용하거나, 다른 자료 구조를 고려해야 한다.
동적 배열은 프로그램 실행 중에 크기가 변경될 수 있는 배열이다. 정적 배열과 달리, 초기 생성 시 미리 크기를 정확히 알지 못하거나 데이터 양이 변동할 수 있는 상황에서 유용하게 사용된다. 많은 현대 프로그래밍 언어는 동적 배열을 표준 라이브러리나 핵심 자료 구조로 제공하며, 대표적으로 C++의 std::vector, 자바의 ArrayList, 파이썬의 list가 이에 해당한다.
동적 배열은 내부적으로 고정된 크기의 배열을 사용하여 요소를 저장한다. 요소를 추가하다가 내부 배열의 공간이 부족해지면, 더 큰 크기의 새로운 배열을 할당하고 기존 데이터를 모두 복사하는 방식으로 용량을 확장한다. 이 재할당 과정은 일정한 시간이 소요되므로, 성능을 고려할 때 중요한 요소가 된다. 일반적으로 용량을 두 배로 늘리는 전략을 사용하여, 재할당 발생 빈도를 줄이고 전체적인 삽입 효율을 높인다.
동적 배열의 주요 연산 성능은 상황에 따라 다르다. 마지막 위치에 요소를 추가하거나 제거하는 것은 평균적으로 매우 빠르지만(O(1)), 배열의 중간에 요소를 삽입하거나 삭제할 경우 해당 위치 이후의 모든 요소를 이동시켜야 하므로 비효율적일 수 있다(O(n)). 또한 인덱스를 통한 임의 접근은 정적 배열과 마찬가지로 매우 빠르다(O(1)).
동적 배열은 연결 리스트와 자주 비교된다. 연결 리스트는 중간 삽입/삭제가 빠르고 크기 변경이 유연하지만, 임의 접근이 느리고 각 요소마다 추가 메모리(포인터)를 사용한다는 단점이 있다. 반면 동적 배열은 캐시 지역성 덕분에 순차 접근 속도가 매우 빠르고 메모리 오버헤드가 적다는 장점이 있어, 무작위 접근이 빈번하거나 대량의 데이터를 순차적으로 처리할 때 선호된다.
배열의 접근은 인덱스를 사용하여 특정 위치의 요소를 읽거나 쓰는 연산이다. 배열은 메모리에 연속적으로 할당되기 때문에, 첫 번째 요소의 메모리 주소인 베이스 주소에 인덱스와 요소의 크기를 곱한 값을 더하면 해당 요소의 주소를 즉시 계산할 수 있다. 이 주소 산술 덕분에 배열의 접근 시간은 요소의 위치와 무관하게 상수 시간(O(1))에 이루어진다. 이는 배열이 임의 접근이 가능한 자료 구조로 분류되는 핵심 이유이다.
대부분의 프로그래밍 언어에서 배열 접근은 대괄호([]) 문법을 사용한다. 예를 들어, array[5]는 배열의 여섯 번째 요소를 의미한다. 여기서 사용되는 인덱스는 일반적으로 0부터 시작하는 제로 베이스 인덱싱 방식을 따른다. 이는 베이스 주소 자체가 0번 인덱스 요소의 주소와 일치하도록 하여 주소 계산을 단순화하는 관례이다.
접근 연산은 배열의 가장 기본적이고 효율적인 연산이다. 알고리즘에서 특정 데이터를 빠르게 조회해야 할 때, 또는 반복문을 통해 모든 요소를 순회할 때 이 접근 방식을 활용한다. 다차원 배열의 경우에도 접근 원리는 동일하며, 여러 개의 인덱스를 사용하여 요소의 위치를 지정한다. 예를 들어, 2차원 배열에서 matrix[2][3]은 세 번째 행의 네 번째 열에 있는 요소를 가리킨다.
배열의 탐색은 배열에 저장된 모든 요소를 순서대로 방문하여 처리하는 연산이다. 주로 반복문을 사용하여 구현되며, 배열의 첫 번째 요소부터 마지막 요소까지 차례대로 접근한다. 이 과정은 각 요소의 인덱스를 0부터 (배열 크기 - 1)까지 순차적으로 증가시키며 수행된다.
탐색은 배열에 저장된 데이터를 출력하거나, 합계를 계산하거나, 특정 조건을 만족하는 요소를 찾는 등 다양한 목적으로 사용된다. 순차 탐색 알고리즘은 배열 탐색의 가장 기본적인 예시로, 배열의 처음부터 끝까지 선형적으로 검색하여 원하는 값을 찾는다.
배열 탐색의 시간 복잡도는 일반적으로 O(n)이다. 이는 배열의 크기에 비례하여 시간이 선형적으로 증가함을 의미한다. 따라서 매우 큰 배열을 탐색할 경우 성능에 영향을 미칠 수 있다. 이러한 이유로 대규모 데이터에서 빠른 검색이 필요할 때는 이진 탐색이나 해시 테이블과 같은 다른 자료 구조가 고려되기도 한다.
대부분의 프로그래밍 언어는 for 루프나 while 루프를 통해 배열 탐색을 지원한다. 특히 자바스크립트의 forEach 메서드나 파이썬의 for ... in 구문처럼 언어별로 제공하는 특수한 반복문을 활용하면 더 간결하게 배열을 탐색할 수 있다.
배열에서 요소를 삽입하거나 삭제하는 연산은 배열의 고정된 크기와 연속된 메모리 배치 특성 때문에 제약이 따른다. 삽입 연산은 특정 인덱스 위치에 새로운 요소를 추가하는 것이다. 만약 배열의 중간이나 시작 부분에 삽입해야 한다면, 해당 인덱스 이후의 모든 요소를 한 칸씩 뒤로 이동시켜 빈 공간을 만들어야 한다. 이 요소 이동 과정 때문에 최악의 경우(배열 맨 앞에 삽입) 시간 복잡도는 O(n)이 된다. 반면 배열의 끝에 요소를 추가하는 것은 일반적으로 O(1)의 시간이 소요된다.
삭제 연산은 특정 인덱스의 요소를 제거하는 것이다. 삽입과 유사하게, 중간이나 시작 부분의 요소를 삭제하면 배열의 연속성을 유지하기 위해 삭제된 위치 이후의 모든 요소를 앞으로 한 칸씩 당겨와야 한다. 따라서 이 경우에도 요소 이동이 필요하며, 시간 복잡도는 O(n)이다. 배열의 마지막 요소를 삭제하는 것은 별도의 이동이 필요 없어 상수 시간에 가능하다.
이러한 연산의 비효율성은 정적 배열의 근본적인 한계에서 비롯된다. 배열의 크기가 컴파일 시간에 고정되어 있기 때문에, 삽입 시 배열의 용량이 부족해지면 더 큰 새로운 배열을 할당하고 모든 기존 요소를 복사해야 하는 추가 비용이 발생할 수 있다. 이러한 문제를 해결하기 위해 동적 배열 자료 구조가 고안되었다. 대표적인 예로 자바의 ArrayList나 C++의 std::vector는 내부적으로 배열을 사용하면서도 필요에 따라 용량을 자동으로 조절한다.
따라서 빈번한 중간 삽입과 삭제가 필요한 시나리오에서는 연결 리스트와 같은 다른 자료 구조가 더 적합할 수 있다. 연결 리스트는 물리적 연속성을 요구하지 않아 노드의 삽입과 삭제가 상대적으로 빠르게 이루어진다. 배열은 임의 접근이 빈번하고 데이터의 크기가 비교적 안정적인 상황에서 그 장점을 발휘한다.
배열의 가장 큰 장점은 인덱스를 통한 빠른 임의 접근 성능이다. 각 요소는 메모리에 연속적으로 저장되어 있기 때문에, 특정 위치의 요소를 찾기 위해 처음부터 순차적으로 탐색할 필요가 없다. 대신 시작 주소와 인덱스, 요소의 크기만으로 바로 해당 메모리 위치를 계산해 접근할 수 있어, 접근 시간 복잡도는 O(1)로 매우 효율적이다. 이 특성은 검색 알고리즘이나 데이터를 자주 조회해야 하는 상황에서 큰 강점이 된다.
또한, 메모리 사용이 효율적이라는 점도 장점이다. 모든 데이터가 연속된 공간에 배치되므로, 실제 데이터를 저장하는 데 필요한 메모리 외에 추가적인 포인터나 메타데이터를 저장할 공간이 거의 필요하지 않다. 이는 연결 리스트 같은 다른 자료 구조와 비교할 때 명확한 차이점이다. 구조가 단순하여 컴파일러나 런타임 환경에서 최적화하기도 상대적으로 쉽다.
배열은 반복문과 결합하여 사용하기에 매우 적합한 구조다. 인덱스가 순차적으로 증가하는 특성 때문에 for 문이나 while 문을 이용해 모든 요소를 체계적으로 순회하거나 처리하는 코드를 직관적이고 간결하게 작성할 수 있다. 이는 대량의 데이터를 일괄 처리하거나 행렬 계산을 수행할 때 특히 유용하다.
마지막으로, 캐시 지역성을 활용하기 좋다는 점도 성능상 중요한 이점이다. 데이터가 물리적으로 인접해 저장되어 있기 때문에, 하나의 요소를 접근할 때 그 주변의 요소들도 함께 캐시 메모리에 로드될 가능성이 높다. 이로 인해 이후 접근하는 인접 요소에 대한 처리 속도가 빨라져, 전체적인 프로그램의 실행 성능을 높이는 데 기여한다.
배열의 가장 큰 단점은 크기가 고정되어 있다는 점이다. 정적 배열은 선언 시점에 그 크기를 결정하며, 프로그램 실행 중에 이를 쉽게 변경할 수 없다. 이는 필요한 데이터의 양을 미리 예측하기 어려운 상황에서 비효율을 초래한다. 너무 큰 크기로 선언하면 메모리 낭비가 발생하고, 너무 작게 선언하면 배열의 범위를 벗어나는 오류가 발생하거나 더 큰 동적 배열이나 연결 리스트와 같은 다른 자료 구조로의 전환이 필요해진다.
또 다른 단점은 배열 중간에 요소를 삽입하거나 삭제하는 연산이 비효율적이라는 것이다. 특정 인덱스에 새 요소를 삽입하려면, 그 뒤에 있는 모든 요소들을 한 칸씩 뒤로 이동시켜 공간을 만들어야 한다. 삭제할 때도 마찬가지로, 빈 자리를 채우기 위해 뒤의 요소들을 앞으로 당겨와야 한다. 이러한 이동 연산은 평균적으로 O(n)의 시간 복잡도를 가지므로, 데이터 양이 많을수록 성능에 부정적인 영향을 미친다.
메모리 측면에서도 배열은 항상 연속된 메모리 공간을 요구한다는 제약이 있다. 매우 큰 배열을 할당하려면 그만큼의 연속된 메모리 블록이 필요하며, 시스템의 메모리 단편화가 심한 경우 할당 자체가 실패할 수 있다. 이는 동적 메모리 할당의 어려움으로 이어진다. 또한, 배열은 동일한 자료형의 데이터만 저장할 수 있어, 서로 다른 타입의 데이터를 하나의 집합으로 관리해야 할 때는 부적합하다. 이러한 경우에는 구조체의 배열이나 연관 배열을 고려하게 된다.
대부분의 프로그래밍 언어는 배열을 핵심 자료 구조로 지원하지만, 그 구현 방식과 문법, 제공하는 기능에는 차이가 있다. C와 C++에서는 배열이 메모리의 연속된 공간을 차지하는 가장 기본적인 형태로, 크기가 컴파일 타임에 결정되는 정적 배열이 일반적이다. 자바의 배열은 객체로 취급되며, 생성 시 크기를 지정하면 변경할 수 없지만, 배열 변수 자체는 다른 배열 객체를 참조할 수 있다. 파이썬에서는 list가 동적 배열의 역할을 하며, 서로 다른 자료형의 요소를 저장할 수 있는 유연성을 제공한다. 한편, 자바스크립트의 배열도 객체 기반의 동적 배열이며, 길이가 가변적이다.
저수준 언어와 고수준 언어 간의 배열 처리 방식 차이는 주로 메모리 관리와 관련이 깊다. C 언어에서는 배열의 경계를 프로그래머가 직접 관리해야 하며, 메모리 접근 오류가 발생하기 쉽다. 반면, 자바나 C#과 같은 언어는 배열의 인덱스 범위를 검사하는 경계 검사를 수행하여 안전성을 높인다. 또한, 자바 가상 머신이나 .NET과 같은 관리되는 환경에서는 가비지 컬렉션 덕분에 배열 메모리의 해제를 신경 쓰지 않아도 된다.
다차원 배열의 구현도 언어마다 다르다. C 계열 언어에서는 배열의 배열 형태로 구현되는 것이 일반적이다. 포트란이나 MATLAB과 같은 과학 계산용 언어는 행렬 연산에 최적화된 진정한 다차원 배열을 기본적으로 지원하기도 한다. 이러한 차이는 각 언어의 설계 철학과 주된 사용 목적을 반영한다.
배열은 다양한 프로그래밍 시나리오에서 핵심적인 역할을 한다. 가장 기본적인 활용은 동일한 성격의 데이터를 순차적으로 관리하는 것이다. 예를 들어, 학생 100명의 점수를 저장하거나 한 달 동안의 일일 기온 데이터를 기록할 때 1차원 배열을 사용한다. 이러한 데이터는 반복문과 결합되어 효율적으로 처리될 수 있으며, 인덱스를 통한 빠른 접근 덕분에 특정 학생의 점수나 특정 날짜의 기온을 즉시 조회하는 것이 가능하다.
표나 행렬 형태의 데이터를 표현할 때는 다차원 배열이 필수적이다. 가장 흔한 형태인 2차원 배열은 체스판이나 바둑판 같은 격자형 게임 맵, 스프레드시트의 셀, 디지털 이미지의 픽셀 데이터를 표현하는 데 사용된다. 3차원 배열은 볼륨 렌더링이나 과학 계산에서 3차원 공간 데이터를 모델링할 때 활용된다.
알고리즘 구현에서도 배열은 빼놓을 수 없는 도구이다. 정렬 알고리즘은 대부분 배열에 저장된 데이터를 대상으로 하며, 검색 알고리즘 역시 정렬된 배열에서 특정 값을 찾는 과정에서 중요하게 다뤄진다. 또한, 버퍼나 큐와 같은 간단한 자료 구조를 구현할 때도 배열이 기반이 된다. 문자열 역상 많은 프로그래밍 언어에서 문자의 배열 또는 배열과 유사한 형태로 처리된다.
고성능 계산이 요구되는 수치 해석, 데이터 분석, 머신러닝 분야에서는 대규모 데이터 세트를 배열 형태로 메모리에 올려 연산한다. 행렬 연산은 이러한 분야의 기초를 이루며, 벡터화된 연산을 지원하는 현대의 라이브러리들은 내부적으로 배열의 효율적인 처리를 통해 성능을 극대화한다.
연결 리스트는 배열과 함께 가장 기본적인 선형 자료 구조 중 하나이다. 배열이 연속된 메모리 공간에 데이터를 저장하는 반면, 연결 리스트는 각 데이터 요소를 노드라는 독립된 단위로 저장하고, 이 노드들이 포인터(또는 링크)를 통해 논리적으로 연결되는 방식으로 구성된다.
연결 리스트의 핵심 구조는 데이터를 담는 필드와 다음 노드의 주소를 가리키는 포인터 필드로 이루어진 노드이다. 이 포인터 체인을 따라가면 리스트 전체를 순회할 수 있다. 배열과 달리 물리적 메모리상에서 연속될 필요가 없기 때문에, 메모리 할당이 더 유연하다는 특징이 있다. 이로 인해 데이터의 삽입과 삭제 연산이 특정 위치에서 상대적으로 빠르게 이루어질 수 있다.
그러나 이러한 구조는 임의 접근이 불가능하다는 단점을 동시에 가진다. 즉, i번째 요소에 접근하려면 리스트의 처음(head)부터 순차적으로 i번 이동해야 하므로 접근 시간은 O(n)이 된다. 이는 인덱스를 통해 즉시 접근이 가능한 배열(O(1))과 대비되는 부분이다. 또한, 각 노드가 다음 노드의 주소를 저장하기 위한 추가적인 메모리 공간(포인터)을 필요로 한다.
연결 리스트는 단순 연결 리스트, 이중 연결 리스트, 원형 연결 리스트 등 여러 변형이 존재하며, 스택이나 큐와 같은 다른 추상 자료형을 구현하는 데 기반이 되기도 한다. 배열과 연결 리스트의 장단점을 이해하는 것은 특정 문제에 적합한 자료 구조를 선택하는 데 중요하다.
동적 배열은 프로그램 실행 중에 크기가 변경될 수 있는 배열이다. 일반적인 정적 배열은 선언 시 크기가 고정되지만, 동적 배열은 필요에 따라 요소를 추가하거나 제거하면서 내부 배열의 크기를 자동으로 조절한다. 많은 현대 프로그래밍 언어의 표준 라이브러리에서 제공하는 리스트나 벡터가 바로 동적 배열의 일종이다.
동적 배열의 핵심 동작 원리는 미리 일정량의 여유 공간을 할당해 두는 것이다. 요소가 계속 추가되어 현재 할당된 용량을 초과하면, 더 큰 새로운 연속 메모리 공간을 할당받고 기존의 모든 데이터를 새 공간으로 복사한다. 이 과정을 재할당이라고 하며, 성능에 영향을 줄 수 있어 전략적으로 처리된다. 대표적인 구현 방식으로는 용량이 가득 찼을 때 현재 크기의 두 배로 공간을 늘리는 전략이 널리 사용된다.
동적 배열은 정적 배열의 장점인 빠른 임의 접근 속도를 유지하면서도 유연한 크기 조정이 가능하다는 점에서 매우 유용하다. 자료 구조의 기본이 되며, 스택이나 큐와 같은 다른 추상 자료형을 구현하는 데에도 자주 활용된다. 다만, 배열 중간에 요소를 삽입하거나 삭제하는 연산은 여전히 비효율적일 수 있으며, 재할당 과정에서 일시적인 성능 저하가 발생할 수 있다는 점은 단점으로 꼽힌다.
배열은 현대 컴퓨터 시스템의 메모리 구조와 밀접하게 연관되어 있다. 메모리가 선형 주소 공간으로 구성되어 있고, 프로세서가 주소를 통해 메모리에 직접 접근하는 방식이기 때문에, 연속된 주소에 데이터를 배치하는 배열의 개념은 매우 자연스럽게 등장했다. 이는 배열이 하드웨어의 특성을 효율적으로 반영한 추상화라고 볼 수 있다.
역사적으로 배열은 가장 오래되고 기본적인 자료 구조 중 하나이다. 초기 프로그래밍 언어인 포트란(FORTRAN)에서부터 핵심 기능으로 제공되었으며, 이후 등장한 C 언어에서는 배열과 포인터의 관계를 통해 메모리 접근의 근본 원리를 보여주었다. 이러한 저수준 접근성 덕분에 배열은 시스템 프로그래밍, 임베디드 시스템, 고성능 컴퓨팅 분야에서 여전히 필수적인 역할을 한다.
배열의 단순함은 오히려 그 강점이 된다. 복잡한 포인터 연산이나 동적 메모리 할당 없이도 데이터를 체계적으로 관리할 수 있어, 학습자에게 자료 구조의 시작점을 제공한다. 또한 CPU 캐시의 지역성 원리를 잘 활용할 수 있어, 대규모 데이터를 순차적으로 처리할 때 현대 컴퓨터 아키텍처에서 매우 높은 성능을 발휘한다.
많은 고급 자료 구조들도 내부적으로는 배열을 기반으로 구현된다. 예를 들어, 힙, 해시 테이블, 벡터나 ArrayList 같은 동적 배열은 모두 배열을 확장하거나 보완한 개념이다. 이는 배열이 컴퓨팅의 근간을 이루는 핵심 요소임을 방증한다.