🥞 스택(Stack)

데이터를 마지막에 밀어 넣고, 마지막에 밀어 넣은 데이터를 먼저 꺼내는 후입 선출(LIFO,Last In First Out) 방식의 자료구조. 스택은 언제나 가장 마지막에 넣은 최신 데이터를 먼저 취득한다. 스택에 데이터를 밀어 넣는 것을 푸시(push), 데이터를 꺼내는 것을 팝(pop)이라 한다.

🔎 스택 활용 예시

후입선출 특징으로 여러 분야에서 활용

  • 웹 브라우저 방문기록(뒤로가기)
  • 실행 취소(undo)
  • 역순 문자열 만들기
  • 후위 표기법 계산

[ 스택을 이용한 실행 취소(undo) 예제 ]

class UndoStack {
  constructor() {
    this.stack = [];
  }

  // 작업을 스택에 추가
  push(action) {
    this.stack.push(action);
  }

  // 실행취소 기능
  undo() {
    if (this.stack.length > 0) {
      const action = this.stack.pop();
      action.undo(); // 작업을 취소하는 함수 호출
    } else {
      console.log("실행취소할 작업이 없습니다.");
    }
  }
}

// 실행취소할 작업 객체 예제
const document = {
  text: "",
  setText(text) {
    this.text = text;
  }
};

// 실행취소할 작업을 정의한 객체
const setTextAction = {
  previousText: "",
  execute(text) {
    this.previousText = document.text;
    document.setText(text);
  },
  undo() {
    document.setText(this.previousText);
  }
};

// 실행취소 스택 생성
const undoStack = new UndoStack();

// 사용자 작업 예제
setTextAction.execute("Hello, World!");
undoStack.push(setTextAction);

setTextAction.execute("Updated text.");
undoStack.push(setTextAction);

console.log("현재 텍스트:", document.text); // 출력: Updated text.

// 실행취소 수행
undoStack.undo();
console.log("실행취소 후 텍스트:", document.text); // 출력: Hello, World!

=> 이 코드에서는 UndoStack 클래스를 정의하여 스택을 생성하고, 작업 객체인 setTextAction을 만들어 스택에 저장한다. 사용자가 작업을 수행할 때마다 해당 작업을 setTextAction.execute(text)로 실행하고, 스택에 추가한다. 실행취소가 요청되면 undoStack.undo() 메서드가 가장 최근에 저장된 작업을 꺼내어 undo() 함수를 호출하여 작업을 취소한다.


🫸🏻 큐(Queue)

데이터를 마지막에 밀어 넣고, 가장 먼저 밀어 넣은 데이터(처음 데이터)를 먼저 꺼내는 선입 선출(FIFO,First In First Out) 방식의 자료구조. 큐는 언제나 데이터를 밀어 넣은 순서대로 데이터를 취득한다. 큐에 데이터를 밀어 넣는 것을 푸시(push), 데이터를 꺼내는 것을 쉬프트(shift)이라 한다.

🔎 큐 활용 예시

선입선출 특징으로 순서대로 처리해야 하는 경우 활용

  • 프린터의 인쇄 대기열
  • 은행 업무
  • 너비 우선 탐색(BFS)
  • 콜센터 고객 대기 시간
  • 캐시(Cache) 구현
  • 선입선출이 필요한 대기열 (티켓 카운터)

[큐를 이용한 대기 처리 예제]

class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(element) {
    this.items.push(element);
  }

  dequeue() {
    if (this.isEmpty()) {
      return "대기열이 비어 있습니다.";
    }
    return this.items.shift();
  }

  isEmpty() {
    return this.items.length === 0;
  }

  size() {
    return this.items.length;
  }
}

// 대기열 생성
let waitQueue = new Queue();

// 대기열에 요청 추가
waitQueue.enqueue("요청 1");
waitQueue.enqueue("요청 2");
waitQueue.enqueue("요청 3");

console.log("대기열에 있는 요청 수:", waitQueue.size()); // 출력: 3

// 요청 처리 시뮬레이션
console.log("처리된 요청:", waitQueue.dequeue()); // 출력: "요청 1"
console.log("대기열에 있는 요청 수:", waitQueue.size()); // 출력: 2

console.log("처리된 요청:", waitQueue.dequeue()); // 출력: "요청 2"
console.log("대기열에 있는 요청 수:", waitQueue.size()); // 출력: 1

console.log("처리된 요청:", waitQueue.dequeue()); // 출력: "요청 3"
console.log("대기열에 있는 요청 수:", waitQueue.size()); // 출력: 0

console.log("처리된 요청:", waitQueue.dequeue()); // 출력: "대기열이 비어 있습니다."

=> 이 코드에서는 Queue 클래스를 사용하여 대기열을 관리한다. enqueue 메서드로 요청을 추가하고, dequeue 메서드로 요청을 처리하면서 대기열에서 제거. 처리되지 않은 요청이 남아있을 경우 계속해서 처리할 수 있다.


✏️ TIL

※ Reference

profile
🚀 Front-end Dev

0개의 댓글