배열과 스택

taeyul_de·2025년 2월 18일
0

배열이란?

배열은 순서가 있는 데이터 저장소이다.

각 요소는 인덱스(index) 를 통해 접근할 수 있으며, 데이터를 연속된 메모리 공간에 저장한다.

JavaScript에서 배열은 동적 배열로 구현되어 있으며, 크기가 자동으로 조정된다.

배열은 다양한 메서드를 제공하여 데이터를 쉽게 추가, 삭제, 정렬할 수 있다.


배열의 특징

  1. 인덱스를 사용하여 빠르게 접근할 수 있다.

• arr[0], arr[1]과 같은 방식으로 요소를 가져올 수 있다.

  1. 배열의 크기는 동적으로 변경된다.

• 새로운 요소를 추가하면 크기가 자동으로 늘어나고, 요소를 삭제하면 줄어든다.

  1. 배열의 중간 요소를 삭제하면 재정렬이 필요하다.

• 특정 요소를 삭제하면 뒤에 있는 요소들이 한 칸씩 앞으로 이동해야 한다.

  1. 배열은 객체로 구현되어 있다.

• JavaScript의 배열은 실제로 객체이며, length 속성과 다양한 메서드를 제공한다.


배열의 주요 메서드

메서드설명시간 복잡도
push(value)배열의 끝에 값을 추가한다O(1)
pop()배열의 끝 값을 제거한다O(1)
unshift(value)배열의 앞에 값을 추가한다O(n)
shift()배열의 앞 값을 제거한다O(n)
splice(index, count)특정 위치의 요소를 추가 또는 삭제한다O(n)
slice(start, end)특정 범위의 요소를 복사하여 새로운 배열을 만든다O(n)
map(callback)배열의 각 요소에 콜백 함수를 적용한 새로운 배열을 반환한다O(n)
filter(callback)특정 조건을 만족하는 요소만을 포함하는 새로운 배열을 반환한다O(n)
reduce(callback, initialValue)배열을 순회하며 누적 연산을 수행한다O(n)

배열의 내부 동작

배열은 연속된 메모리 공간에 데이터를 저장하지만, JavaScript의 배열은 동적 배열이므로

공간이 부족할 경우 새로운 메모리를 할당하고 기존 데이터를 복사하는 과정이 발생한다.

배열의 인덱스 접근은 O(1)의 시간 복잡도를 가지지만, 중간 삽입 및 삭제는 O(n) 이 된다.

const arr = ["🍎", "🍌", "🍇"]; // 메모리 구조 예시
// 메모리 구조:
// 0x100 -> "🍎"
// 0x104 -> "🍌"
// 0x108 -> "🍇"

배열의 길이를 초과하여 요소를 추가하면 새로운 메모리를 할당하고 데이터를 복사하는 작업이 발생한다.


배열의 활용 예시

  1. 데이터 저장 및 관리

• JSON 데이터 구조를 다룰 때 배열을 사용한다.

  1. UI 요소 관리

• React와 같은 프레임워크에서 상태(state) 관리 시 배열을 사용한다.

  1. 정렬 및 검색

• 배열을 정렬(sort())하거나 특정 조건에 맞는 요소를 찾을 때(filter(), find()) 사용한다.

2차원 배열

2차원 배열은 1차원 배열을 확장한 것 이다. 2차원 배열은 다음과 같이 선언할수있다.

//  2 차원 배열을 리터럴로 표현
const arr = l[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]1;

//  arr[2][3] 에 저장된 값을 출력
console. Log(arr [2J[3]); / / 12

//  arr[2][3]에 저장된 값을 15로 변경
arr[2J[3] = 15;

//  변경된 값을 출 력
console. log(arr[2][3]); / / 15

스택이란?

스택은 후입선출(LIFO, Last In First Out) 방식으로 동작하는 자료구조이다.

데이터의 추가(push())와 제거(pop())가 맨 위(Top)에서만 이루어진다.

배열을 사용하여 쉽게 구현할 수 있으며, 실행 취소(Undo), 함수 호출 스택(Call Stack) 등 다양한 곳에서 사용된다.


스택의 특징

  1. 후입선출(LIFO) 구조를 가진다.

• 마지막에 추가된 요소가 가장 먼저 제거된다.

  1. 맨 위(Top)에서만 데이터 추가 및 삭제가 가능하다.

• 중간의 요소를 제거할 수 없으며, 반드시 마지막 요소부터 제거해야 한다.

  1. 배열을 사용하여 쉽게 구현할 수 있다.

• JavaScript의 push()와 pop()을 활용하면 간단하게 스택을 구현할 수 있다.


스택의 주요 메서드

메서드설명시간 복잡도
push(value)스택의 맨 위에 값을 추가한다O(1)
pop()스택의 맨 위 값을 제거한다O(1)
peek()스택의 맨 위 값을 반환한다 (제거하지 않음)O(1)
isEmpty()스택이 비어 있는지 확인한다O(1)
size()스택의 크기를 반환한다O(1)

스택의 내부 동작

스택은 데이터를 배열의 끝에 추가하고(push()), 끝에서 제거(pop())하는 방식으로 동작한다.

이로 인해 O(1)의 시간 복잡도를 가지며, 매우 빠른 데이터 추가 및 삭제가 가능하다.

// 스택 구현 (배열 사용)
const stack = [];

// 데이터 추가
stack.push("🟥 빨강");
stack.push("🟦 파랑");
stack.push("🟩 초록");

console.log(stack); // ["🟥 빨강", "🟦 파랑", "🟩 초록"]

// 데이터 제거
const lastItem = stack.pop();
console.log(lastItem); // "🟩 초록" (마지막에 넣은 값이 먼저 나옴)
console.log(stack); // ["🟥 빨강", "🟦 파랑"]

스택의 활용 예시

  1. 실행 취소(Undo) 기능

• 문서 편집기에서 실행 취소할 때 마지막 작업을 먼저 제거하는 방식으로 동작한다.

  1. 브라우저 뒤로 가기(History) 관리

• 사용자가 방문한 페이지를 스택에 저장하고, “뒤로 가기” 버튼을 누르면 최근 페이지부터 제거하는 방식이다.

  1. 함수 호출 스택(Call Stack)

• JavaScript의 함수 실행 과정에서 콜 스택(Call Stack)이 사용되며, 후입선출 방식으로 실행된다.

function first() {
  console.log("첫 번째 실행");
  second();
}

function second() {
  console.log("두 번째 실행");
  third();
}

function third() {
  console.log("세 번째 실행");
}

first();

실행 과정

  1. first() 실행 → 스택에 first() 추가
  2. first() 안에서 second() 실행 → 스택에 second() 추가
  3. second() 안에서 third() 실행 → 스택에 third() 추가
  4. third() 실행 완료 → 스택에서 제거
  5. second() 실행 완료 → 스택에서 제거
  6. first() 실행 완료 → 스택에서 제거

이처럼 실행이 끝난 함수는 마지막 실행된 함수부터 제거되며, 후입선출(LIFO) 방식으로 동작한다.

배열 vs 스택 비교

개념배열(Array)스택(Stack)
구조순차적으로 데이터를 저장후입선출 (LIFO)
추가 방식push(), unshift() 등 자유롭게 가능push() (맨 위에서만 추가)
제거 방식pop(), shift(), splice() 등 가능pop() (맨 위에서만 제거)
접근 방식index를 사용하여 특정 요소 접근 가능맨 위 요소(top)만 접근 가능
사용 예시리스트, 데이터 관리실행 취소(Undo), 콜 스택(Call Stack)

배열과 스택의 개념을 깊이 이해하면, 다양한 알고리즘과 데이터 구조를 쉽게 이해할 수 있다.

배열은 데이터 저장과 검색에 유용하고, 스택은 후입선출 방식이 필요한 곳에서 강력한 성능을 발휘한다.


추상 자료형 = ADT(Abstract Data Type)

ADT는 자료구조를 어떻게 구현할지보다는, 무엇을 할 수 있는지를 정의하는 개념적인 모델이다.
어떤 연산을 제공해야 하는지 명확하게 정의하는 것이 핵심이며, 내부 구현 방식은 중요하지 않다.

쉬운 예로 자동차와 운전자의 관계를 들수있다.
자동차를 운전할 때 자동차의 내부 엔진 구조를 몰라도 엑셀을 밟으면 가속하고, 브레이크를 밟으면 멈춘다는 기능만 알면된다.

profile
이래서 되겠나 싶은 개발지망생

0개의 댓글