덱 (Deque)
CS/자료구조
스택은 한쪽 끝에서만, 큐는 양쪽 끝이지만 각각 다른 작업(삽입/삭제)만 가능했다.그렇다면 양쪽 끝에서 삽입과 삭제를 모두 자유롭게 할 수 있다면 어떨까? 바로 그것이 덱(Deque, Double-Ended Queue)이다.덱덱은 Double-Ended Queue의 약자로, 데이터의 삽입과 제거를 head와 tail 두 곳 모두에서 자유롭게 할 수 있는 자료구조이다. 스택과 큐의 기능을 모두 포함하는 더 유연한 구조라고 할 수 있다.스택, 큐, 덱 비교 스택 (Stack)큐 (Queue)덱 (Deque)삽입 위치한쪽 끝뒤쪽양쪽 끝 모두삭제 위치한쪽 끝 (같은 곳)앞쪽양쪽 끝 모두구조LIFOFIFO자유로움활용뒤로 가기, Undo대기열, BFS슬라이딩 윈도우 등 덱의 핵심 연산덱은 다음과 같은 기본 연산을 ..
큐 (Queue)
CS/자료구조
은행 창구나 마트 계산대를 떠올려보자.먼저 온 사람이 먼저 처리를 받고, 나중에 온 사람은 뒤에서 기다린다. 이것이 큐(Queue)의 핵심 개념이다. 스택이 "가장 최근 것을 먼저"라면, 큐는 "먼저 온 것을 먼저" 처리하는 공정한 자료구조이다. 큐큐는 FIFO(First-In-First-Out) 구조를 가지는 자료구조이다.먼저 들어온 데이터가 먼저 나가는 구조로, 스택과 정반대의 특성을 가지고 있다.스택 vs 큐 스택 (Stack)큐 (Queue)구조LIFO (후입선출)FIFO (선입선출)비유접시 쌓기줄서기삽입push (한쪽 끝)enqueue (뒤쪽)삭제pop (같은 쪽 끝)dequeue (앞쪽) 큐의 핵심 연산큐는 다음과 같은 기본 연산을 제공한다.enqueue(): 큐의 뒤쪽에 데이터를 추가dequ..
스택 (Stack)
CS/자료구조
접시를 쌓을 때를 생각해보자.아래에서부터 차곡차곡 쌓아 올리고, 사용할 때는 가장 위에 있는 접시부터 꺼내게 된다.이것이 바로 스택(Stack)의 핵심 개념이다. 스택스택은 FILO(First-In-Last-Out) 또는 LIFO(Last-In-First-Out) 구조를 가지는 자료구조이다.즉, 먼저 들어온 데이터가 나중에 나가고, 나중에 들어온 데이터가 먼저 나가는 구조이다.스택의 핵심 연산스택은 다음과 같은 기본 연산을 제공한다.push(): 스택의 맨 위에 데이터를 추가pop(): 스택의 맨 위에서 데이터를 제거하고 반환peek(): 스태그이 맨 위 데이터를 제거하지 않고 확인isEmpty(): 스택이 비어있는지 확인 연결 리스트로 스택 구현하기스택은 배열로도 구현할 수 있지만, 이전 글에서 다룬 ..
연결리스트 (Linked List)
CS/자료구조
배열배열은 프로그래밍에서 가장 기본적이고 많이 사용되는 자료구조이다.하지만 배열에도 분명한 한계가 있다.배열의 장단점배열의 장점빠른 접근 속도: 인덱스를 통한 읽기/쓰기가 O(1)의 시간복잡도를 가진다.메모리의 연속성: 데이터가 연속적으로 저장되어 캐시 효율성이 좋다.배열의 단점고정된 크기: 배열을 선언할 때 크기를 미리 정해야 하므로, 필요한 크기를 예측하기 어려운 경우 메모리 낭비가 발생할 수 있다.비효율적인 삽입/삭제: 중간에 데이터를 삽입하거나 삭제할 때, 뒤에 있는 모든 요소를 이동시켜야 한다. 연결 리스트연결 리스트(Linked List)는 배열의 단점을 보완하기 위해 만들어진 자료구조이다.각 요소(노드)가 데이터와 다음 노드를 가리키는 포인터로 구성되어 있어, 메모리상에서 연속적으로 배치될 ..
HashMap 직접 구현하기
CS/자료구조
자바스크립트의 Map을 배열만으로 직접 구현해보면서 해시맵의 동작 원리를 이해하는 과정을 정리했다. 구현 목표자바스크립트의 Map 기본 동작을 따라서 문자열 키-값 해시맵을 구현한다.단, Object, Map 등을 사용하지 않고 오직 배열로만 구현해야 한다.구현할 메서드clear(): 전체 맵 초기화containsKey(String): 키 존재 여부 반환get(String): 키에 해당하는 값 반환isEmpty(): 빈 맵 여부 반환keys(): 전체 키 목록을 배열로 반환put(String key, String value): 키-값 추가remove(String key): 키에 해당하는 값 삭제size(): 전체 아이템 개수 반환 사전 학습구현에 앞서 필요한 개념들을 먼저 정리했다.배열과 리스트배열은 메..
new Array(length).map()으로 배열 초기화시 콜백이 실행되지 않는 문제
Dev Log
자바스크립트에서 배열을 초기화하려고 new Array(4).map(() => [])을 사용했는데 의도대로 동작하지 않았다. 원인을 찾아보니 JavaScript의 빈 슬롯과 undefined의 차이, 그리고 map() 메서드가 빈 슬롯에 대해 콜백을 실행하지 않는다는 특성 때문이었다. 문제 상황특정 크기의 배열을 만들고 각 요소를 []로 초기화하려고 했다.const result = new Array(4).map(() => []);console.log(result); // 기대: [[], [], [], []] 하지만 실제 결과는 달랐다.console.log(result); // [empty × 4]console.log(result[0]); // undefined 원인 분석빈 슬롯 vs undefined자바스..
에러 메시지와 스택 트레이스 분석을 통해 문제 해결하기
Dev Log
자바스크립트로 카드 게임 로직을 구현하던 중 TypeError: Cannot read properties of undefined라는 에러를 만났다. 코드가 복잡하고 짐작가는 부분이 단번에 떠오르지 않아 막막했는데, 에러 메시지와 스택 트레이스를 차근차근 분석해가며 원인을 찾아낸 과정을 기록해본다. 에러 발생게임 로직을 테스트하던 중 특정 입력에서 다음과 같은 에러가 발생했다.TypeError: Cannot read properties of undefined (reading 'array') at getLastElement (03.debug.js:45:19) at submitCard (03.debug.js:85:7) at processPlayerAction (03.debug.js:103:3)..
적절한 함수명과 단일 책임으로 코드 개선하기
TIL
이 글에서는 자바스크립트로 구현된 보드게임의 로직을 개선하는 과정을 다루며,개선 과정은 함수명 개선 → 중복 제거 → 책임 분리의 단계로 이루어져 있다.작동하지만 개선이 필요한 코드주어진 코드는 기능적으로는 문제없이 동작했지만, 더 나은 방식을 고민하다 보니 여러 개선점을 찾을 수 있었다.function checkLadder(position) { switch (position) { case 4: return 14; case 8: return 30; case 21: return 42; // ... default: return null; }}function checkSnake(position) { switch (position) { case 32: return 10; ..
Vanilla JS로 클라이언트 사이드 라우팅과 검색 기능 구현하기
Frontend/JavaScript
이 글에서는 SPA에서 페이지 새로고침 없이 URL을 변경하고 검색 기능을 구현하는 방법을 알아본다.History API를 활용한 클라이언트 사이드 라우팅은 프레임워크 없이도 효과적인 SPA를 구현할 수 있는 핵심 기술이다.클라이언트 사이드 라우팅 구현History API 활용history.pushState()를 사용하면 페이지 새로고침 없이 브라우저의 URL을 변경할 수 있다.// App.jshandleClick: async () => { // 브라우저 히스토리에 새 항목 추가 (URL을 홈으로 변경) history.pushState(null, null, "/"); // 포켓몬 목록 데이터 다시 불러오기 const pokemonList = await getPokemonList(); // 앱 전..
Vanilla JS 컴포넌트 설계 패턴
Frontend/JavaScript
바닐라 자바스크립트로 SPA를 구현할 때 컴포넌트 패턴을 활용하면 코드의 재사용성과 유지보수성을 크게 향상시킬 수 있다.이 글에서는 React와 같은 프레임워크 없이 순수 자바스크립트만으로 컴포넌트 기반 아키텍처를 구현하는 방법을 알아본다.바닐라 JS 컴포넌트 설계 패턴애플리케이션 진입점 설정SPA의 시작점에서 애플리케이션을 초기화한다.import App from './App.js';const $app = document.querySelector('#app');new App($app);App 컴포넌트가 #app DOM 요소에 마운트되어 애플리케이션이 시작된다. $app 요소는 전체 애플리케이션의 최상위 컨테이너 역할을 한다. 부모 컴포넌트 구현부모 컴포넌트는 애플리케이션의 상태를 관리하고 자식 컴포넌트들..