배열(Array)이란 무엇인가

2020.03.06

메인

배열(Array)란?

배열은 가장 간단한 데이터구조이다.

연속적인 값들을 저장할때 그 값들 각각에 대한 변수를 선언하면 코드도 길어지고 관리하기 어려워지므로 배열을 사용한다.
한 개의 변수에 값들을 연속적으로 저장함으로써 많은 데이터를 효율적으로 저장하고 관리할 수 있다.
순서가 있는 데이터를 관리할 때 주로 사용한다.

데이터가 빈틈없이 연속적으로 나열되는 자료구조이다.
실제로 메모리에서도 물리적으로 연속적으로 나열되는 형태로 구현된다.

배열의 장점

임의 접근(random access)이 가능하므로, N번째 요소를 조회하는 데 있어서 성능이 빠르다.

데이터가 연속적으로 저장되어있으므로, 변수가 저장된 메모리 주소만 알면 배열의 요소는 배열의 인덱스로 한 번에 빠르게 조회할 수 있다. - O(1) 실행시간

배열의 단점

메모리 낭비가 생길 수 있다.

배열을 저장할 공간을 만들때 여분 메모리도 확보하게 되는데 그 과정에서 메모리 낭비가 생길 수 있다.

데이터의 삽입/삭제가 비효율적이다.

데이터를 삽입/삭제 후 나머지 배열 요소들의 위치를 모두 옮겨줘야하므로 성능이 좋지 않다. - O(n) 실행시간

구현 - JavaScript에서의 배열

가장 간단하고 기본적인 자료구조라 대부분의 프로그래밍 언어에서 기본으로 구현하여 내장 타입으로 제공하므로 따로 구현할 필요는 없다.

JavaScript에서도 기본으로 제공되는 Array 객체를 사용하면 된다.

사용

// 배열의 선언 & 초기화
const arr = ["A", "B", "C"];

// 배열 요소 조회
console.log(arr[2]); // -> "C"

특징

  • 다른 언어들과 다르게 배열의 요소로 다양한 타입의 데이터가 들어갈 수 있다.
    (그래도 하나의 타입만 쓰는게 관리하기 편하다)
  • JS의 배열은 엄밀히 말해 진짜 배열은 아니다.

    • 다른 프로그래밍 언어와 달리 JS의 배열은 객체로 배열의 기능을 흉내낸 것이다.
    • 배열의 인덱스를 문자열로 변환해서 객체 프로퍼티의 Key로 사용하는식으로 구현했다.
      (아래 코드의 arr1이 내부적으로는 arr2로 구현됨)
    const arr1 = ["A", "B", "C"];
    
    const arr2 = {
      "0": "A",
      "1": "B",
      "2": "C",
    };
    • JavaScript의 객체가 연관배열로 구현되어있으니, JS 배열도 연관배열로 구현되어있는 셈이다.
  • 실제 메모리의 물리적 공간에 연속으로 배치되는 진짜 배열을 사용하고 싶다면, ES6부터 제공되는 TypedArray 객체를 통해 사용할 수 있다.

    • 그러나 보통의 경우는 Array를 사용해도 무방하다. 3D렌더링처럼 성능이 아주 중요해지는 경우에 TypedArray를 사용하면 유용하다고 한다.

확장 - 다차원 배열

배열을 중첩하는 방식으로 구현한다

// 1차원 배열
const arr1 = ["A", "B"];

// 2차원 배열
const arr2 = [
  ["A", "B"],
  ["C", "D"],
];

// 3차원 배열
const arr3 = [
  [
    ["A", "B"],
    ["C", "D"],
  ],
  [
    ["E", "F"],
    ["G", "H"],
  ],
];

확장 - 링 버퍼 Ring Buffer

Circular Buffer, Circular Array라고도 하며,
배열의 마지막 요소와 배열의 1번째요소를 연결시킨 자료구조이다.

실제로는 마지막 Index 다음의 요소가 존재하지 않지만, 배열의 마지막요소의 다음요소를 배열의 첫번째요소가 되게 함으로써 구현한다.

function CircularArray(maxLength) {
  this.maxLength = maxLength;
}

CircularArray.prototype = Object.create(Array.prototype);

CircularArray.prototype.push = function(element) {
  Array.prototype.push.call(this, element);
  while (this.length > this.maxLength) {
    this.shift();
  }
};

활용 사례

최근 통화이력 처럼 가장 오래된 데이터를 버리는 FIFO의 큐 구조 구현할때 유용하다.

  • 아디트야 바르가바, 『Hello Coding 그림으로 개념을 이해하는 알고리즘』, 김도형, 한빛미디어(2017)
  • 스기우라 켄, 『그림으로 배우는 알고리즘』, 서재원, 영진(2016)
  • 이소 히로시, 『모던 자바스크립트 입문』, 서재원, 길벗(2018)
  • Martin Erwig, 『그들은 알고리즘을 알았을까?』, 송원형, 영진(2017)
  • Loiane Groner, 『자바스크립트 자료 구조와 알고리즘』, 이일웅, PACKT-에이콘(2015)
글쓴이쿠스, Qus
직업은 소프트웨어 개발자.
기술로 사회문제를 해결하는 시빅해킹(Civic Hacking)에 관심이 많고,
이것저것 생각나는 것들을 글로 정리하는 것을 좋아합니다.