자료구조

[자료구조] 스택(Stack)

개발 집사 2025. 4. 13. 12:51

1. 스택이란?

스택(Stack)은 데이터를 차곡차곡 쌓고,
나중에 쌓은 데이터를 먼저 꺼내는 후입선출(Last-In-First-Out, LIFO) 구조의 자료구조이다.

접시를 한 장씩 쌓고 맨 위에서부터 꺼내는 구조를 떠올리면 이해가 쉽다.

 


 

2. 스택을 왜 다뤄야 할까?

프로그래밍을 하다 보면, 데이터를 순서대로 저장하고, 가장 마지막에 저장한 데이터를 가장 먼저 꺼내야 하는 상황이 자주 발생한다. 예를 들면 다음과 같다:

  • 웹 브라우저의 뒤로 가기: 방문한 페이지를 순서대로 스택에 쌓고, 가장 마지막 페이지부터 꺼낸다.
  • 재귀 호출 처리: 함수 호출은 스택 메모리에 쌓이고, 종료 시 LIFO 구조로 되돌아간다.
  • 문법 검사기: 괄호 짝 검사, 수식 유효성 검사 등에 사용된다.
  • 문자열 뒤집기: 한 글자씩 스택에 넣고 pop하면 역순 출력이 가능하다.

 


 

3. 스택 구현을 메서드

자바스크립트로 Stack을 구현하면서 주요 기능을 정리해보았다.

✅ 생성자 함수: Stack(array)

function Stack(array) {
  this.array = array ? array : [];
}
  • 초기값으로 배열을 전달받으면 해당 값으로 스택을 초기화하며, 전달하지 않으면 빈 배열로 시작된다.

✅ getBuffer()

Stack.prototype.getBuffer = function () {
  return this.array.slice();
};
  • 스택 내부 배열의 복사본을 반환한다. 원본 변경 없이 외부에서 데이터를 조회할 때 유용하다.

✅ isEmpty()

Stack.prototype.isEmpty = function () {
  return this.array.length === 0;
};
  • 스택이 비어 있으면 true, 아니면 false를 반환한다.

✅ push(element)

Stack.prototype.push = function (element) {
  return this.array.push(element);
};
  • 데이터를 스택의 맨 위에 추가한다.

✅ pop()

Stack.prototype.pop = function () {
  return this.array.pop();
};
  • 가장 마지막에 추가된 데이터를 제거하고 반환한다.

✅ peek()

Stack.prototype.peek = function () {
  return this.array[this.array.length - 1];
};
  • 스택의 top 값을 제거하지 않고 확인만 한다.

✅ size()

Stack.prototype.size = function () {
  return this.array.length;
};
  • 스택에 들어 있는 요소의 개수를 반환한다.

✅ indexOf(element, position = 0)

Stack.prototype.indexOf = function (element, position = 0) {
  for (let i = position; i < this.array.length; i++) {
    if (element === this.array[i]) return i;
  }
  return -1;
};
  • 특정 요소의 위치(index)를 반환하며, position부터 탐색을 시작한다.

✅ includes(element, position = 0)

Stack.prototype.includes = function (element, position = 0) {
  for (let i = position; i < this.array.length; i++) {
    if (element === this.array[i]) return true;
  }
  return false;
};
  • 특정 값이 스택에 존재하는지를 확인한다.

 


 

5. 전체 예제 코드

// Stack(): 생성자 함수
function Stack(array) {
  this.array = array ? array : [];
}

// getBuffer(): 객체 내 데이터 셋 반환
Stack.prototype.getBuffer = function () {
  return this.array.slice();
};

// isEmpty(): 객체 내 데이터 O/X
Stack.prototype.isEmpty = function () {
  return this.array.length === 0;
};

// push(): 데이터 추가
Stack.prototype.push = function (element) {
  return this.array.push(element);
};

// pop(): 데이터 삭제
Stack.prototype.pop = function () {
  return this.array.pop();
};

// peek(): 가장 끝 데이터 반환
Stack.prototype.peek = function () {
  return this.array[this.array.length - 1];
};

// size(): 스택 내 데이터 개수 확인
Stack.prototype.size = function () {
  return this.array.length;
};

// indexOf(): 매개변수로 넘어온 element 위치 확인
Stack.prototype.indexOf = function (element, position = 0) {
  for (let i = position; i < this.array.length; i++) {
    if (element === this.array[i]) return i;
  }
  return -1;
};

// includes(): 데이터 존재 여부 확인
Stack.prototype.includes = function (element, position = 0) {
  for (let i = position; i < this.array.length; i++) {
    if (element === this.array[i]) return true;
  }
  return false;
}

let stack = new Stack([1, 2, 3, 4]);

console.log(stack);                 // Stack { array: [1, 2, 3, 4] }

let data = stack.getBuffer();

console.log(data);                 // [1, 2, 3, 4]
console.log(data === stack.array); // false

console.log(stack.isEmpty());      // false

stack.push(5);

console.log(stack);                // Stack { array: [1, 2, 3, 4, 5] }

console.log(stack.pop());          // 5
console.log(stack.pop());          // 4

console.log(stack.peek());         // 3

console.log(stack.size());         // 3

console.log(stack.indexOf(1));     // 0
console.log(stack.indexOf(1, 2));  // -1 → 2번 인덱스부터 찾았지만 1은 존재하지 않음
console.log(stack.indexOf(3, 2));  // 2  → 2번 인덱스에 3이 존재함

console.log(stack.includes(1));    // true
console.log(stack.includes(5));    // false

 

 


 

마무리 인사이트 ✍️

이번 글에서는 스택의 개념부터 구현까지 순차적으로 정리하였다.
직접 스택을 구현해보면 구조와 동작 원리를 자연스럽게 익힐 수 있고,

단순한 push, pop 외에도 다양한 부가 기능을 통해 유용하게 응용할 수 있다.