Stack(스택)과 Queue(큐) 자료구조
Stack(스택)
스택이란?
1.
저장: 항상 위에만 저장한다
2.
읽기: 항상 제일 위에 있는 데이터만 읽을 수 있다
3.
삭제: 항상 제일 위에 있는 데이터만 삭제 할 수 있다
스택의 용도
•
STACK은 위 규칙을 가진 전용자료구조 이고 배열을 이용해서 구현해도 좋고 또는 LIST를 이용해서 구현해도 좋다. 구현 방법은 개발자의 자유다.
•
실생활 예시: 접시 쌓기, 책 쌓기, 되돌리기(Undo) 기능 등
링크드리스트 기반 스택 구현
#pragma once
#include <iostream>
#include <string>
#include <vector>
struct Node
{
int data;
Node* next;
};
Node* top = nullptr; // 🔝 스택의 최상단을 가리키는 포인터
Node* bottom = nullptr; // 🔚 스택의 바닥을 가리키는 포인터
// 📥 Stack - 요소 추가
void push(int value)
{
Node* buff = new Node(); // 🆕 새 노드 생성
buff->data = value; // 📝 데이터 저장
buff->next = top; // 🔗 기존 최상단을 다음으로 연결
top = buff; // 🔝 새 노드를 최상단으로 설정
}
// 📤 Stack - 요소 제거
void pop()
{
Node* backup = top; // 🗂️ 삭제할 노드 백업
top = top->next; // 🔝 최상단을 다음 노드로 이동
delete backup; // 🗑️ 메모리 해제
}
// 👁️ Stack - 최상단 요소 확인
int Top()
{
return top->data; // 🔍 최상단 데이터 반환
}
C++
복사
push(1) → [1]
push(3) → [3] → [1]
push(2) → [2] → [3] → [1]
pop() → [3] → [1] // 2가 제거됨
Plain Text
복사
배열 기반 스택 구현
#pragma once
#include <iostream>
#include <string>
#include <vector>
int mArr[256] = {}; // 📦 스택 저장 배열
int top = -1; // 📍 현재 최상단 위치 (-1: 비어있음)
// 📥 Stack - 요소 추가
void push(int value)
{
mArr[++top] = value; // 📈 top 증가 후 데이터 저장
}
// 📤 Stack - 요소 제거
void pop()
{
if (top == -1) // 🚫 스택이 비어있는지 확인
{
// 빈 스택에서 pop 시도
}
else
{
top--; // 📉 top만 감소 (실제 데이터는 덮어쓰기됨)
}
}
// 👁️ Stack - 최상단 요소 확인
int Top()
{
if (top == -1) // 🚫 스택이 비어있는지 확인
{
std::cout << "Stack is empty" << std::endl;
return -1;
}
else
{
std::cout << "Top value : " << mArr[top] << std::endl;
return mArr[top];
}
}
C++
복사
초기 상태: mArr[256] = {}, top = -1
push(1): top = 0, mArr[0] = 1
push(3): top = 1, mArr[1] = 3
push(2): top = 2, mArr[2] = 2
push(5): top = 3, mArr[3] = 5
현재 상태:
Index: [0][1][2][3][4]...
Value: [1][3][2][5][ ]...
↑
top
Plain Text
복사
Queue(큐)
큐란?
•
여러 함수에서 신호들이 한꺼번에 들어오면, 순차 처리를 위한 대기열 용도로 사용된다
큐의 특징
•
스택: pop할때, 가장 마지막에 들어온 값을 가장 먼저 제거한다
•
큐: pop할때, 가장 처음에 들어온 값을 가장 먼저 제거한다
큐의 시각적 표현
🎯 Queue 동작:
A함수 ───┐
│ Queue: [□][□][□][□][□][□][□][□] ───→ Run
B함수 ───┤ 순서대로 차곡차곡 요청 신호, 정보를 넣어 둠 (업무 중 신호 순서대로
│ 처리할 하나씩 꺼내서
C함수 ───┘ 처리 해 줌)
Plain Text
복사
링크드리스트 기반 큐 구현
#include <iostream>
#include <string>
#include <list>
#include <assert.h>
#include <vector>
#include <stack>
#include <queue>
struct Node
{
int data;
Node* next;
};
Node* head = nullptr; // 🏁 큐의 앞쪽 (제거되는 쪽)
Node* tail = nullptr; // 🔚 큐의 뒤쪽 (추가되는 쪽)
// 📥 Queue - 요소 추가 (뒤쪽에 추가)
void push(int value)
{
if (head == nullptr) // 🏠 첫 번째 요소인 경우
{
Node* buff = new Node();
buff->data = value;
head = buff;
tail = buff;
}
else // 🔗 기존 요소가 있는 경우
{
tail->next = new Node(); // 🆕 새 노드를 tail 다음에 연결
tail = tail->next; // 🔚 tail을 새 노드로 이동
tail->data = value; // 📝 데이터 저장
}
}
// 📤 Queue - 요소 제거 (앞쪽에서 제거)
void pop()
{
Node* backup = head; // 🗂️ 삭제할 노드 백업
head = head->next; // 🏁 head를 다음 노드로 이동
delete backup; // 🗑️ 메모리 해제
}
// 👁️ Queue - 앞쪽 요소 확인
int top()
{
return head->data; // 🔍 가장 앞쪽 데이터 반환
}
C++
복사
push(1): head→[1]←tail
push(3): head→[1]→[3]←tail
push(2): head→[1]→[3]→[2]←tail
push(5): head→[1]→[3]→[2]→[5]←tail
pop(): head→[3]→[2]→[5]←tail // 1이 제거됨 (FIFO)
Plain Text
복사
Stack vs Queue 비교
구분 | Stack | Queue |
원리 | LIFO (후입선출) | FIFO (선입선출) |
추가위치 | top (맨 위) | rear/tail (맨 뒤) |
제거위치 | top (맨 위) | front/head (맨 앞) |
실생활 예시 | 접시 쌓기, Undo 기능 | 대기줄, 프린터 작업 대기열 |
주요 용도 | 함수 호출, 재귀, 괄호 검사 | 작업 스케줄링, BFS |
구현 방식 선택
배열 기반 vs 링크드리스트 기반
•
장점: 구현 간단, 빠른 접근
•
단점: 크기 제한, 메모리 낭비 가능
•
장점: 동적 크기, 메모리 효율적
•
단점: 포인터 오버헤드, 구현 복잡
핵심 포인트
•
push(): 맨 위에 추가
•
pop(): 맨 위에서 제거
•
top(): 맨 위 요소 확인
•
push(): 맨 뒤에 추가
•
pop(): 맨 앞에서 제거
•
front(): 맨 앞 요소 확인
•
빈 자료구조에서 pop(), top() 호출 시 예외 처리 필요
•
동적 할당 시 메모리 해제 잊지 않기
•
인덱스 범위 체크 (배열 기반의 경우)
이 두 자료구조는 프로그래밍에서 매우 기본적이면서도 중요한 개념이므로, 구현 원리를 정확히 이해하고 활용할 수 있어야 합니다! 
“강의는 많은데, 왜 나는 아직도 코드를 못 짤까?”
혼자 공부하다 보면 누구나 이런 고민을 하게 됩니다.
•
강의는 다 들었지만 막상 손이 안 움직이고,
•
복습을 하려 해도 무엇을 다시 봐야 할지 모르겠고,
•
질문할 곳도 없고,
•
유튜브는 결국 정답을 따라 치는 것밖에 안 되는 것 같고.
문제는 ‘연습’이 빠졌기 때문입니다.
단순히 강의를 듣는 것만으로는 실력이 늘지 않습니다.
실제 문제를 풀고, 고민하고, 직접 구현해보는 시간이 반드시 필요합니다.
그래서, 얌얌코딩 코칭은 다릅니다.
그냥 가르치지 않습니다.
스스로 설계하고, 코딩할 수 있게 만듭니다.
얌얌코딩 코칭에서는 단순한 예제가 아닌,
스스로 문제를 분석하고 구현해야 하는 연습문제를 제공합니다.
이 연습문제들은 다음과 같은 역량을 키우기 위해 설계되어 있습니다:
•
문제를 스스로 쪼개고 설계하는 힘
•
다양한 조건을 만족시키는 실제 구현 능력
•
기능 단위가 아닌, 프로그램 단위로 사고하는 습관
•
마침내 자신의 힘으로 코드를 끝까지 작성하는 경험
지금 필요한 건 더 많은 강의가 아닙니다.
코드를 스스로 완성해 나가는 훈련,
그것이 지금 실력을 끌어올릴 가장 현실적인 방법입니다.