← 목록으로
컴퓨팅·임베디드
#자료구조#스택#큐#리스트#LIFO#132회#125회
최종 업데이트 · 2026-09-28

선형 자료구조: 스택 · 큐 · 리스트

1. 개요

가. 정의

데이터를 일렬(선형·1차원)로 나열해 저장하며, 각 원소가 앞뒤 원소와 1:1로만 인접하는 자료구조로, 입출력 규칙에 따라 스택(LIFO)·큐(FIFO)·리스트(임의 접근) 로 나뉜다.

선형 자료구조는 트리·그래프 같은 비선형 구조와 달리, 원소 간 관계가 "이전-다음"이라는 단순한 순서로만 정의된다. 각 원소는 최대 하나의 앞 원소와 하나의 뒤 원소만 갖기 때문에 구조가 직관적이고 구현이 단순하다. 언뜻 단순해 보이지만, 입출력을 어디서 허용하느냐에 따라 전혀 다른 성질과 용도가 생긴다는 점이 이 계열의 핵심이다. 스택·큐는 접근 지점을 의도적으로 제한(양 끝 또는 한 끝)해 특정 처리 순서를 강제하고, 리스트는 제한 없이 임의 위치 접근을 허용한다.

이 "접근 제한"이라는 렌즈로 보면 세 구조는 하나의 스펙트럼 위에 놓인다. 접근을 가장 강하게 제한한 것이 스택(한 끝), 그다음이 큐(양 끝을 역할로 분리), 제한이 없는 것이 리스트다. 제한이 강할수록 연산은 단순해지고 특정 순서가 보장되지만 유연성은 줄고, 제한이 없을수록 유연하지만 원소를 찾거나 옮기는 비용이 커진다. 자료구조 학습에서 이 셋을 함께 다루는 이유가 바로 이 대비에 있다.

역설적이지만 제한은 곧 힘이다. 스택이 중간 접근을 포기한 덕분에 "가장 최근 것부터"라는 순서를 별도 정렬 없이 보장하고, 큐가 삽입·삭제 지점을 분리한 덕분에 "먼저 온 것부터"를 자동으로 지킨다. 만약 리스트로 이런 순서를 구현하려면 매번 위치를 관리하는 추가 로직이 필요하다. 즉 접근을 제한하는 특수 구조는 특정 문제에 대해 더 단순하고 안전한 코드를 만들어 주며, 이것이 범용 리스트가 있는데도 스택·큐를 따로 두는 이유다.

나. 등장 배경 및 필요성

프로그램은 데이터를 "어떤 순서로 넣고 꺼내는가"에 따라 알고리즘의 정확성과 효율이 갈린다. 예컨대 함수 호출은 마지막에 호출된 함수가 먼저 끝나야 하므로 LIFO가 자연스럽고, 프린터 대기열은 먼저 요청한 작업이 먼저 처리돼야 하므로 FIFO가 자연스럽다. 이처럼 문제마다 요구되는 처리 순서가 정해져 있고, 자료구조는 그 순서를 구조 자체로 보장해 주는 도구다.

자료구조 선택은 결국 문제의 접근 패턴에 맞춰 연산 비용을 최소화하기 위한 설계 결정이다. 같은 데이터라도 어떤 구조에 담느냐에 따라 핵심 연산이 O(1)이 되기도 하고 O(n)이 되기도 한다. 잘못된 구조를 고르면 논리적으로는 맞아도 성능이 무너지고, 반대로 접근 패턴에 맞는 구조를 고르면 코드가 단순해지면서 성능도 좋아진다. 선형 자료구조는 이 "구조가 곧 규칙"이라는 원리를 가장 명료하게 보여 주는 출발점이다.

또한 스택·큐·리스트는 그 자체로 쓰일 뿐 아니라 더 복잡한 자료구조와 알고리즘의 기본 부품이 된다. 트리의 깊이 우선 순회는 스택으로, 너비 우선 순회는 큐로 구현되고, 해시 충돌 처리의 체이닝은 연결 리스트로 만든다. 따라서 이 세 구조의 성질을 정확히 이해하는 것은 이후 모든 자료구조·알고리즘 학습의 토대가 된다.

역사적으로도 이 구조들은 컴퓨팅 초기부터 존재했다. 스택은 서브루틴 호출과 복귀를 처리하기 위해 하드웨어·언어 차원에서 도입됐고, 큐는 일괄 처리(batch) 시대의 작업 대기열에서 비롯됐다. 오늘날의 CPU도 함수 호출을 스택 포인터 레지스터로 관리하며, 운영체제 스케줄러는 큐 위에서 동작한다. 즉 이 세 구조는 추상 개념이면서 동시에 실제 하드웨어·시스템 소프트웨어에 물리적으로 구현돼 있는 근본 도구다.

2. 전체 구조와 스택(Stack)

flowchart TB
  subgraph Linear["선형 자료구조"]
    S["스택 (LIFO)"]
    Q["큐 (FIFO)"]
    L["리스트 (임의 접근)"]
  end
  S -->|"한 끝만 입출력"| U1["함수호출·undo·DFS"]
  Q -->|"양 끝 역할 분리"| U2["스케줄링·버퍼·BFS"]
  L -->|"제한 없음"| U3["범용 순차 관리"]

위 개념도는 세 구조가 접근 제한의 정도에 따라 갈라지고 각기 다른 용도로 이어짐을 보여 준다. 이제 각 구조를 순서대로 깊이 살펴본다.

flowchart TB
  P["Push 삽입"] --> T(("Top"))
  T --> O["Pop 삭제"]

스택은 한쪽 끝(Top)에서만 삽입·삭제가 일어나는 LIFO(Last In First Out) 구조다. 접시를 쌓았다가 위에서부터 꺼내는 것과 같아, 가장 나중에 넣은 데이터가 가장 먼저 나온다. 삽입(push)·삭제(pop)·최상단 조회(peek)가 모두 Top 한 지점만 건드리므로 각 연산은 O(1)로 끝난다. 중간 원소에는 직접 접근할 수 없다는 제약이 있지만, 바로 그 제약이 "가장 최근 것부터 처리"라는 순서를 공짜로 보장한다.

이 LIFO 성질은 "되돌아가야 하는" 문제에서 강력하다. 대표적으로 함수 호출 스택은 호출→반환의 중첩 관계를 그대로 표현한다. 함수 A가 B를, B가 C를 부르면 C가 먼저 끝나고 B, A 순으로 반환되는데, 이 역순 반환이 정확히 LIFO다. 재귀 호출이 깊어지면 이 스택이 넘쳐 스택 오버플로가 발생하는 것도 같은 원리다. 편집기의 undo(실행 취소) 역시 가장 최근 작업부터 되돌려야 하므로 스택으로 구현하며, undo·redo를 두 개의 스택으로 짝지어 관리하면 되돌리기와 다시 실행을 자연스럽게 지원한다.

구현 관점에서 스택은 배열로도, 연결 리스트로도 만들 수 있다. 배열 기반은 Top을 가리키는 인덱스 하나만 두면 되어 단순하고 캐시 효율이 좋지만 최대 크기 제약이 있고, 연결 리스트 기반은 크기 제약이 없는 대신 노드마다 포인터 오버헤드가 있다. 어느 쪽이든 사용자에게 보이는 push/pop 인터페이스와 O(1) 성능은 동일하며, 이 "겉은 같고 속만 다른" 특성이 뒤에서 다룰 추상 자료형(ADT) 개념으로 이어진다.

계산·탐색 영역에서도 스택은 핵심이다. 수식의 괄호 짝 검사는 여는 괄호를 push하고 닫는 괄호에서 pop해 짝을 맞추며, 중위→후위 표기 변환과 후위표기 계산도 스택으로 연산자·피연산자를 관리한다. 그래프·트리의 DFS(깊이 우선 탐색) 는 "한 경로를 끝까지 파고들었다가 막히면 되돌아오는" 동작이 스택의 push/pop과 일치해, 명시적 스택이나 재귀(암묵적 호출 스택)로 구현된다.

스택이 이렇게 다양한 문제에 두루 쓰이는 근본 이유는, 중첩(nesting)과 역순 처리라는 패턴이 컴퓨팅 전반에 반복해서 나타나기 때문이다. 괄호의 중첩, 함수 호출의 중첩, HTML/XML 태그의 중첩, 탐색 경로의 되돌아오기는 모두 "가장 안쪽(가장 최근) 것부터 닫는다"는 동일한 구조를 갖는다. 스택은 이 패턴을 자료구조 하나로 포착하므로, 겉보기에 무관해 보이는 문제들이 실은 같은 해법으로 풀린다.

항목 내용
원리 LIFO — Top에서만 입출력
연산 push(삽입)·pop(삭제)·peek(조회), 모두 O(1)
제약 중간 원소 임의 접근 불가
활용 함수 호출 스택, undo, 수식 계산, DFS

3. 큐(Queue)

큐는 뒤(rear)에서 삽입(enqueue)하고 앞(front)에서 삭제(dequeue) 하는 FIFO(First In First Out) 구조로, 사람들이 줄 서는 모습과 같다. 먼저 들어온 데이터가 먼저 나가므로 공정한 순서(도착 순 처리) 가 필요한 곳에 쓰인다. 스택이 "최근 우선"이라면 큐는 "선착순"이며, 이 차이가 두 구조의 용도를 완전히 갈라놓는다.

큐의 대표 활용은 자원 대기와 속도차 흡수다. 운영체제의 작업·프로세스 스케줄링에서 준비 큐는 도착 순으로 CPU를 배분하고, 프린터·네트워크 요청도 요청 순으로 처리해 굶주림(starvation) 없이 공정성을 유지한다. 특히 생산 속도와 소비 속도가 다른 두 모듈 사이에 큐를 두면 버퍼(buffer) 로 작동해, 빠른 생산자가 느린 소비자를 기다리지 않고 데이터를 쌓아 둘 수 있다. 키보드 입력 버퍼, 메시지 큐, 스트리밍 버퍼가 모두 이 원리다. 그래프의 BFS(너비 우선 탐색) 도 "가까운 노드부터 차례로" 방문하는 순서가 FIFO와 맞아 큐로 구현된다.

버퍼로서의 큐는 생산자-소비자 문제(producer-consumer) 라는 고전적 동시성 패턴의 중심이다. 여러 생산자가 데이터를 큐에 넣고 여러 소비자가 꺼내 처리하는 구조는, 큐가 완충 지대 역할을 해 양쪽의 속도 변동을 흡수하고 결합도를 낮춘다. 이 발상은 단일 프로그램을 넘어 분산 시스템으로 확장되어, 마이크로서비스 사이를 메시지 큐로 잇는 이벤트 기반 아키텍처의 뿌리가 된다. 큐 하나를 사이에 두는 것만으로 생산자와 소비자가 서로의 존재·속도·가용성을 몰라도 되는 느슨한 결합이 만들어진다.

단순 배열로 큐를 구현하면 문제가 생긴다. dequeue를 반복하면 front가 계속 뒤로 밀려, 배열 앞쪽은 비었는데도 rear가 배열 끝에 닿아 더 못 넣는 공간 낭비가 발생한다. 이를 해결하려고 배열의 끝과 처음을 논리적으로 이어 붙여 빈 앞 공간을 재사용하는 원형 큐(Circular Queue) 를 쓴다. 원형 큐는 모듈러 연산으로 인덱스를 순환시켜, 고정 크기 배열을 낭비 없이 재활용한다. 나아가 양쪽 끝 모두에서 입출력이 가능한 덱(Deque, Double-Ended Queue), 우선순위가 높은 원소부터 꺼내는 우선순위 큐(Priority Queue, 보통 힙으로 구현) 는 큐의 대표적 변형으로, 각각 슬라이딩 윈도우·다익스트라 최단경로 같은 알고리즘에 쓰인다.

덱은 스택과 큐를 모두 포함하는 상위 개념이라는 점에서 흥미롭다. 한쪽 끝만 쓰면 스택, 한쪽에서 넣고 다른 쪽에서 빼면 큐가 되므로, 덱 하나로 두 구조를 대체할 수 있다. 실제로 여러 언어의 표준 라이브러리가 스택·큐를 별도 자료형 대신 덱 구현으로 제공하는 이유가 여기에 있다. 이는 자료구조가 서로 독립적인 것이 아니라 포함·특수화 관계로 엮여 있음을 보여 주는 좋은 예다.

항목 내용
원리 FIFO — rear 삽입·front 삭제
연산 enqueue(삽입)·dequeue(삭제), O(1)
변형 원형 큐, 덱(Deque), 우선순위 큐
활용 작업 스케줄링, 버퍼, BFS

우선순위 큐는 엄밀히는 FIFO가 아니라 "우선순위 순"이라는 점에서 순수 큐와 구분된다. 그럼에도 큐 계열로 묶는 이유는 "넣고(insert) 하나씩 꺼낸다(extract)"는 인터페이스가 같기 때문이다. 이처럼 같은 추상 인터페이스 아래 내부 규칙만 바꿔 다양한 변형을 만드는 것이 자료구조 설계의 전형적 패턴이다.

스택과 큐의 차이를 한 문장으로 대비하면, 스택은 시간을 거스르고 큐는 시간을 따른다. 스택은 가장 최근 사건부터 처리해 "되돌리기"에 맞고, 큐는 가장 오래된 사건부터 처리해 "공정한 순서"에 맞는다. 그래서 실행 취소·역추적(백트래킹)에는 스택이, 요청 처리·이벤트 전달에는 큐가 쓰인다. 어떤 문제가 "최근 것부터"인지 "먼저 온 것부터"인지를 판별하는 것이 두 구조 중 하나를 고르는 결정적 기준이 된다.

4. 리스트(List)

리스트는 접근 위치에 제한을 두지 않아 임의 위치의 삽입·삭제·조회가 모두 가능한 범용 선형 구조다. 스택·큐가 순서를 강제하는 특수 목적 구조라면, 리스트는 순서를 자유롭게 다루는 범용 컨테이너다. 실제로 스택과 큐는 리스트에 접근 제한을 걸어 특수화한 것으로 볼 수도 있어, 리스트는 선형 구조의 가장 일반적인 형태에 해당한다. 다만 "리스트"라는 한 이름 아래 구현 방식이 크게 둘로 갈리고, 그 차이가 성능을 정반대로 만들기 때문에 실무 선택의 핵심이 된다.

배열 리스트(Array List) 는 원소를 연속된 메모리 공간에 나란히 둔다. 인덱스만 알면 시작 주소에서 오프셋을 더해 곧바로 원소에 닿으므로 임의 접근이 O(1) 이고, 메모리가 연속이라 CPU 캐시 적중률이 높아 순회 성능도 좋다. 그러나 중간에 원소를 삽입·삭제하려면 그 뒤 원소를 모두 한 칸씩 밀거나 당겨야 해 O(n) 이 든다. 또 용량이 차면 더 큰 배열을 새로 할당해 통째로 복사해야 하는 재할당 비용도 있다.

연결 리스트(Linked List) 는 각 노드가 데이터와 함께 다음 노드의 주소(포인터)를 들고 있어, 노드들이 메모리 곳곳에 흩어져 있어도 포인터로 연결된다. 삽입·삭제는 앞뒤 노드의 포인터만 고쳐 끼우거나 빼면 되므로 해당 위치를 알고 있을 때 O(1) 이고, 크기가 동적으로 늘고 줄어 재할당이 없다. 대신 특정 순번의 원소를 찾으려면 첫 노드부터 포인터를 따라 순차 이동해야 해 접근이 O(n) 이며, 노드마다 포인터를 저장하는 메모리 오버헤드와 캐시 비효율이 따른다.

정리하면 "조회·순회 위주면 배열 리스트, 중간 삽입·삭제가 잦으면 연결 리스트" 가 원칙이다. 예컨대 값을 자주 검색하고 순회하는 읽기 중심 데이터는 배열이 유리하고, 원소가 수시로 들락거리는 대기열·이력 관리는 연결 리스트가 유리하다. 연결 리스트는 다시 한 방향만 가리키는 단일 연결 리스트, 앞뒤를 모두 가리키는 이중(양방향) 연결 리스트, 끝이 처음으로 이어지는 원형 연결 리스트로 나뉘며, 이중 연결 리스트는 역방향 순회와 특정 노드 삭제에 유리하다.

다만 현대 하드웨어에서는 이 이론적 복잡도만으로 성능을 단정하기 어렵다는 점도 짚어야 한다. 연결 리스트의 삽입이 O(1)이라도 노드가 메모리에 흩어져 있어 캐시 미스가 잦으면, 캐시에 잘 들어맞는 배열의 순차 접근보다 실제로는 느릴 수 있다. 그래서 원소 이동 비용이 크지 않은 소규모 데이터나 순회가 잦은 경우, 실무에서는 이론상 불리해 보이는 배열 리스트가 오히려 빠른 사례가 많다. 복잡도 분석은 필수 출발점이되, 최종 판단은 데이터 규모와 접근 패턴, 하드웨어 특성을 함께 고려해야 한다.

구현 접근 삽입/삭제 특징
배열 리스트 O(1) O(n) 연속 메모리, 캐시 효율, 재할당 비용
연결 리스트 O(n) O(1)* 포인터 연결, 동적 크기, 메모리 오버헤드

* 삽입·삭제 위치를 이미 알고 있을 때 O(1)이며, 위치를 찾는 탐색까지 포함하면 O(n)이다.

5. 비교 및 사례

세 구조의 차이는 결국 "접근을 얼마나 제한하는가"라는 하나의 축에서 비롯된다. 스택·큐는 접근 지점을 제한해 처리 순서(LIFO/FIFO)를 구조적으로 보장하는 대신 임의 접근을 포기했고, 리스트는 임의 접근을 얻는 대신 순서 보장이라는 특성을 내려놓았다. 즉 "무엇을 보장받고 무엇을 포기하는가"의 교환이 세 구조를 가른다.

구분 스택 큐 리스트
입출력 규칙 LIFO FIFO 임의
접근 지점 Top만 Front/Rear 순차 또는 인덱스
핵심 연산 비용 push/pop O(1) enqueue/dequeue O(1) 접근·삽입 상반
대표 용도 DFS·undo·수식 BFS·버퍼·스케줄링 범용 순차 관리

이 교환 관계를 이해하면 "어떤 구조가 가장 좋은가"라는 질문 자체가 성립하지 않음을 알 수 있다. 각 구조는 특정 접근 패턴에 최적화된 도구일 뿐, 절대적 우열은 없다. 스택에 임의 접근을 요구하거나 배열 리스트에 빈번한 앞쪽 삽입을 요구하는 것은 도구를 용도와 어긋나게 쓰는 것이며, 이때 나타나는 성능 저하는 자료구조의 결함이 아니라 선택의 실패다.

구체 사례로 웹 브라우저를 보면 세 구조가 한 프로그램 안에서 공존한다. 뒤로 가기·앞으로 가기는 방문 이력을 스택 두 개로 관리하고(가장 최근 페이지부터 되돌림), 다운로드·요청 처리는 도착 순으로 큐에 넣어 처리하며, 열린 탭 목록은 임의 추가·삭제가 잦아 리스트로 관리한다. 이처럼 하나의 응용에서도 기능마다 접근 패턴이 달라 서로 다른 선형 구조가 함께 쓰인다.

또 다른 사례로 운영체제의 프로세스 관리에서는 준비 큐(FIFO 또는 우선순위 큐)로 실행 순서를 정하고, 각 프로세스의 함수 호출은 호출 스택으로 지역변수와 복귀 주소를 관리한다. 성능 측면 사례로, 10만 개 원소의 리스트에서 앞쪽에 빈번히 삽입하는 작업을 배열 리스트로 하면 매번 O(n) 이동이 누적돼 느려지지만, 연결 리스트로 바꾸면 각 삽입이 O(1)에 가까워 체감 성능이 크게 개선된다. 이 한 번의 선택이 프로그램의 응답성을 좌우한다.

반대 방향의 사례도 있다. 어떤 데이터를 인덱스로 무작위 조회하는 작업이 초당 수만 번 일어난다면, 연결 리스트에서는 매 조회가 O(n) 순차 탐색이 되어 시스템이 마비될 수 있지만 배열 리스트에서는 O(1)로 즉시 끝난다. 이처럼 같은 데이터라도 지배적 연산이 무엇이냐에 따라 최적 구조가 정반대로 뒤집힌다는 점이 리스트 선택의 핵심 교훈이며, 스택·큐·리스트를 함께 배우는 이유이기도 하다.

6. 심화: 추상 자료형(ADT)과 확장 관점

스택·큐·리스트를 더 깊이 이해하려면 추상 자료형(ADT, Abstract Data Type) 개념이 필요하다. 스택은 "push·pop·peek"이라는 연산의 명세(무엇을 하는가)로 정의될 뿐, 그것을 배열로 구현하든 연결 리스트로 구현하든 사용자에게는 동일하게 보인다. 즉 인터페이스(명세)와 구현(내부 저장)을 분리하는 것이 ADT의 핵심이며, 덕분에 성능 요구에 따라 내부 구현을 바꿔도 이를 쓰는 코드는 그대로 유지된다. 스택을 배열 기반에서 연결 리스트 기반으로 교체해도 호출부가 바뀌지 않는 것이 그 예다.

실제 프로그래밍 언어의 표준 라이브러리도 이 원리를 따른다. 예컨대 Java의 ArrayDeque는 스택과 큐 양쪽으로 쓸 수 있는 덱 구현이고, LinkedList는 리스트이자 큐로 동작한다. C++의 std::stack·std::queue는 내부 컨테이너(deque·list 등)를 갈아 끼울 수 있는 어댑터로 설계돼, ADT와 구현 분리의 사상을 그대로 보여 준다. 실무에서 "스택이 필요하다"는 요구는 곧 "LIFO 인터페이스가 필요하다"는 뜻이며, 구체 자료형은 성능 특성에 맞춰 고르면 된다.

확장 관점에서 이 세 구조는 비선형·복합 자료구조를 만드는 기본 블록이다. 트리의 순회는 내부적으로 스택(DFS)·큐(BFS)를 사용하고, 해시 테이블의 충돌 해결(체이닝)은 연결 리스트로 버킷을 잇는다. 그래프 알고리즘 전반이 스택·큐 위에 서 있으며, 우선순위 큐는 다익스트라·프림 같은 최적화 알고리즘의 심장부다. 따라서 선형 구조를 확실히 익히는 것은 이후 자료구조·알고리즘 전체를 지탱하는 기초 체력에 해당한다.

같은 맥락에서 최신 대용량 처리 기술도 이 뿌리를 공유한다. 스트림 처리 엔진의 이벤트 파이프라인, 태스크 스케줄러의 작업 대기열, 로그 수집 시스템의 버퍼는 모두 큐 위에 서 있고, 언두 히스토리·트랜잭션 롤백은 스택의 발상을 따른다. 규모와 구현이 달라져도 "어떤 순서로 넣고 꺼내는가"라는 근본 질문과 그 답인 LIFO·FIFO·임의 접근의 원리는 변하지 않는다.

이 ADT 관점은 실무의 유지보수성과도 직결된다. 인터페이스와 구현이 분리돼 있으면, 초기에는 단순한 배열 기반으로 시작했다가 데이터가 커져 삽입 비용이 문제되면 내부를 연결 리스트나 다른 구조로 교체할 수 있고, 이때 이를 사용하는 상위 코드는 전혀 손대지 않아도 된다. 좋은 설계란 "지금 무엇을 쓰는가"보다 "나중에 무엇으로 바꿀 수 있는가"를 열어 두는 것이며, 선형 자료구조의 ADT 설계는 그 원리를 학습하는 가장 좋은 예제다.

정보관리기술사 관점에서 출제는 단순 정의 비교를 넘어, "특정 문제 상황에 어떤 구조가 적합하고 왜 그런가"를 연산 복잡도와 접근 패턴으로 논증하도록 심화된다. 따라서 답안에서는 각 구조의 원리(LIFO/FIFO/임의)와 대표 연산의 시간복잡도, 그리고 배열 vs 연결의 트레이드오프를 실제 응용 사례와 엮어 설명하는 것이 핵심 전략이다.

7. 고려사항 및 시사점

  • 접근 패턴 우선 설계: 자료구조 선택은 요구되는 처리 순서·접근 패턴에서 출발해야 한다. LIFO가 필요하면 스택, FIFO면 큐, 임의 접근·순차 관리면 리스트를 고르되, 리스트는 다시 접근 위주냐 삽입·삭제 위주냐로 배열/연결을 결정한다. 구조를 먼저 정하고 문제를 끼워 맞추는 순서는 성능 저하로 이어진다.

  • 시간·공간 트레이드오프의 명시적 판단: 배열 리스트의 O(1) 접근과 연결 리스트의 O(1) 삽입은 동시에 얻을 수 없는 교환 관계다. 데이터 규모, 읽기/쓰기 비율, 캐시 지역성, 메모리 여유를 종합해 어느 쪽 비용을 감수할지 정해야 한다. "무엇이 더 빠른가"가 아니라 "어떤 연산이 지배적인가"가 판단 기준이다.

  • 경계·예외 처리의 견고성: 스택의 오버플로/언더플로, 큐의 만원/공백, 리스트의 널 포인터·경계 인덱스 같은 경계 조건을 견고하게 다뤄야 실서비스 안정성이 확보된다. 특히 재귀 기반 알고리즘의 호출 스택 깊이 제한은 스택 오버플로로 직결되므로, 깊은 재귀는 명시적 스택이나 반복문으로 전환하는 설계가 필요하다.

  • 동시성·확장성 고려: 멀티스레드 환경에서 공유 큐·스택은 경쟁 조건이 생기므로 락(lock) 또는 락프리(lock-free) 구조가 필요하다. 대규모 분산 환경에서는 인메모리 큐를 넘어 메시지 큐(Kafka·RabbitMQ 등) 미들웨어로 확장되며, 이때도 FIFO·버퍼링이라는 큐의 본질 원리는 그대로 계승된다. 기본 자료구조의 이해가 대규모 시스템 설계로 이어지는 지점이다.

  • 추상화와 구현 분리의 습관화: 코드에서 구체 자료형(배열·연결 리스트)에 직접 의존하기보다 스택·큐·리스트라는 추상 인터페이스에 의존하도록 설계하면, 성능 요구가 바뀔 때 구현만 교체할 수 있어 변경에 강한 코드가 된다. 자료구조 선택은 한 번으로 끝나는 결정이 아니라 데이터 규모·패턴 변화에 따라 재검토되는 과정임을 전제로 설계하는 태도가 필요하다.


한 줄 요약: 스택은 Top에서만 입출력하는 LIFO, 큐는 rear 삽입·front 삭제의 FIFO, 리스트는 임의 위치 접근·삽입·삭제 가 가능한 선형 자료구조로, 세 구조의 차이는 "접근을 얼마나 제한하는가"에서 비롯되며, 처리 순서·접근 패턴과 배열 vs 연결의 트레이드오프를 근거로 선택해야 하고, 이들은 트리·그래프·해시 등 복합 자료구조를 구성하는 기본 블록이 된다.