Unisquads
로그인
홈
이용약관·개인정보처리방침·콘텐츠정책·© 2026 Unisquads
이용약관·개인정보처리방침·콘텐츠정책
© 2026 Unisquads. All rights reserved.

LIFO (r1)

이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.14 23:09

LIFO

이름

LIFO

전체 명칭

Last In, First Out

분류

자료 구조

유형

추상 데이터 타입

주요 구현체

스택

반대 개념

FIFO

기술적 상세

원리

가장 나중에 저장된 항목이 가장 먼저 제거되는 방식

주요 연산

Push (삽입), Pop (제거 및 반환), Peek/Top (조회)

응용 분야

함수 호출 관리(콜 스택), 알고리즘(되돌리기, 괄호 검사), 메모리 관리

장점

구현이 간단하고, 마지막 데이터 접근이 빠름

단점

중간 데이터 접근이 비효율적임

관련 개념

큐, 데크

시간 복잡도

삽입/삭제: O(1)

1. 개요

LIFO는 'Last In, First Out'의 약자로, '후입선출' 방식의 데이터 관리 원칙을 가리킨다. 이는 데이터를 처리할 때 가장 마지막에 들어온 항목이 가장 먼저 나가는 구조를 의미한다. 이 원리는 자료구조와 시스템 설계의 기본이 되는 핵심 개념 중 하나이다.

LIFO 구조는 일상생활에서도 쉽게 찾아볼 수 있다. 예를 들어, 접시를 쌓아 올린 더미에서 가장 위에 놓인, 즉 가장 마지막에 쌓은 접시를 가장 먼저 꺼내게 된다. 기술 분야에서는 주로 스택이라는 추상 자료형을 통해 구현되며, 스택 메모리 관리, 함수 호출, 알고리즘 등 컴퓨터 과학의 광범위한 영역에서 활용된다.

LIFO의 반대 개념은 FIFO('선입선출') 방식이다. 이 두 방식은 데이터 접근 순서에 있어 근본적인 차이를 보이며, 각각의 장단점에 따라 적합한 응용 분야가 구분된다. LIFO는 특정한 순서로 작업을 되돌리거나, 깊이 우선 탐색이 필요한 상황에서 특히 유용하다.

2. LIFO의 기본 개념

LIFO는 "Last In, First Out"의 약자로, "마지막에 들어간 것이 처음으로 나온다"는 원리를 가진 데이터 처리 방식이다. 이는 데이터를 저장하고 꺼내는 순서가 정해져 있는 추상적인 개념으로, 가장 최근에 추가된 항목이 가장 먼저 제거되거나 접근된다.

이 원리의 가장 대표적인 구현체는 스택 자료구조이다. 스택은 책을 쌓아 올리는 것에 비유할 수 있다. 책을 위에 쌓을수록(푸시, Push), 가장 위에 있는 책(가장 최근에 쌓은 책)을 가장 먼저 꺼낼 수 있다(팝, Pop). 이처럼 LIFO는 데이터의 입력과 출력이 한쪽 끝에서만 이루어지는 선형 구조를 가지며, 이 끝을 보통 '탑(Top)'이라고 부른다. 반대 개념인 FIFO는 "First In, First Out"으로, 줄서기에 비유할 수 있다.

개념

설명

비유

Last In, First Out

가장 나중에 들어온 데이터가 가장 먼저 나감.

접시 쌓기, 책 쌓기

Top

데이터가 삽입되고 삭제되는 한쪽 끝.

쌓인 책의 가장 위

Push

데이터를 스택의 Top에 추가하는 연산.

책을 더 쌓음

Pop

스택의 Top에서 데이터를 꺼내는 연산.

가장 위의 책을 꺼냄

이 기본 개념은 단순하지만, 시간적 순서를 반대로 거슬러 올라가야 하는 다양한 컴퓨팅 문제를 해결하는 데 강력한 기반을 제공한다.

2.1. 정의와 원리

LIFO는 'Last In, First Out'의 약자로, '후입선출' 방식의 데이터 관리 원리를 가리킨다. 이는 데이터를 처리할 때 가장 마지막에 들어온 항목이 가장 먼저 나가는 구조를 의미한다. 책상 위에 쌓아 올린 책 더미를 생각하면 이해하기 쉽다. 가장 위에 새로 올려놓은 책(Last In)을 가장 먼저 꺼낼 수 있으며(First Out), 맨 아래에 있는 책을 꺼내려면 위에 있는 모든 책을 먼저 치워야 한다. 이 원리는 스택이라는 추상 자료형의 핵심 동작 방식이 된다.

LIFO의 작동 원리는 두 가지 기본 연산, 즉 Push와 Pop으로 설명된다. Push 연산은 데이터를 컬렉션의 가장 위(또는 끝)에 추가하는 작업이다. Pop 연산은 가장 최근에 추가된 데이터를 컬렉션에서 제거하고 그 값을 반환하는 작업이다. 이때 데이터에 접근하는 위치는 항상 한 곳(보통 'top'이라고 부름)으로 제한된다. 이러한 제한된 접근 방식은 데이터의 흐름을 엄격하게 제어할 수 있게 해준다.

LIFO 구조는 시간적 순서가 역전되는 특징을 가진다. 즉, 입력된 순서와 출력되는 순서가 정반대가 된다. 이는 특정 문제를 해결하는 데 매우 효율적이다. 예를 들어, 가장 최근에 발생한 이벤트나 가장 나중에 열린 작업을 가장 먼저 처리해야 하는 상황에서 LIFO 원리는 자연스러운 해법을 제공한다.

2.2. 스택(Stack)과의 관계

LIFO는 스택이라는 추상 자료형의 핵심 원리로 작동한다. 스택은 데이터를 저장하고 접근하는 방식을 정의한 것이며, LIFO는 그 방식이 '마지막에 들어온 것이 먼저 나간다'라는 규칙임을 의미한다. 즉, 스택이라는 구조의 동작 원리를 설명하는 것이 LIFO이다.

스택은 일반적으로 세 가지 주요 연산을 제공한다. Push 연산은 데이터를 스택의 맨 위에 추가하고, Pop 연산은 맨 위의 데이터를 제거하여 반환한다. Peek 또는 Top 연산은 맨 위의 데이터를 제거하지 않고 조회만 한다. 이러한 모든 연산이 스택의 한쪽 끝(top)에서만 이루어지므로 LIFO 접근 방식이 자연스럽게 구현된다.

개념

설명

LIFO

Last-In, First-Out의 약자로, 데이터 접근 방식 또는 원리를 지칭한다.

스택

LIFO 원리에 따라 데이터를 조직화하는 추상 자료형(ADT) 또는 자료구조이다.

따라서 LIFO와 스택은 밀접하게 연결된 개념이지만 엄밀히 구분된다. LIFO는 '어떻게'에 대한 원칙이고, 스택은 그 원칙을 따르는 '구체적인 것'이다. 프로그래밍에서 스택 자료구조를 사용한다는 것은 암묵적으로 LIFO 방식을 채택한다는 것을 의미한다.

3. 기술적 구현

LIFO는 배열이나 연결 리스트와 같은 기본적인 자료구조를 이용하여 구현할 수 있다. 배열을 사용할 경우, 데이터를 순차적으로 저장하고 가장 최근에 추가된 요소의 위치를 가리키는 스택 포인터 변수를 관리한다. 연결 리스트를 사용할 경우, 각 노드가 데이터와 다음 노드를 가리키는 참조를 포함하며, 리스트의 헤드(head)가 스택의 최상단을 나타낸다. 배열 기반 구현은 메모리 접근이 빠르지만 크기가 고정될 수 있으며, 연결 리스트 기반 구현은 동적으로 크기를 조절할 수 있지만 노드 관리에 따른 오버헤드가 존재한다[1].

LIFO 구조의 핵심 연산은 주로 세 가지로 구분된다. 첫 번째는 Push 연산으로, 새로운 데이터 항목을 스택의 최상단에 추가하는 작업이다. 두 번째는 Pop 연산으로, 현재 스택의 최상단에 있는 데이터 항목을 제거하고 그 값을 반환한다. 세 번째는 Peek(또는 Top) 연산으로, 최상단 항목을 제거하지 않고 그 값만을 확인한다. 이 연산들은 일반적으로 상수 시간(O(1))에 수행된다.

연산

설명

시간 복잡도

Push

데이터를 스택의 최상단에 추가한다.

O(1)

Pop

스택의 최상단 데이터를 제거하고 반환한다.

O(1)

Peek/Top

스택의 최상단 데이터를 제거하지 않고 조회한다.

O(1)

IsEmpty

스택이 비어 있는지 확인한다.

O(1)

구현 시 주의할 점은 스택 언더플로우와 스택 오버플로우를 처리하는 것이다. 스택 언더플로우는 빈 스택에서 Pop 연산을 시도할 때 발생하며, 스택 오버플로우는 배열 기반 구현에서 할당된 메모리 공간을 초과하여 Push 연산을 시도할 때 발생한다. 이러한 예외 상황에 대한 처리는 구현의 안정성을 위해 필수적이다.

3.1. 자료구조 구현 (배열, 연결 리스트)

LIFO 구조는 주로 배열과 연결 리스트라는 두 가지 기본적인 자료구조를 사용하여 구현된다. 각 구현 방식은 고유한 장단점을 가지며, 사용되는 메모리 관리 방식과 연산의 효율성에 차이가 있다.

배열을 이용한 구현은 연속된 메모리 공간에 데이터를 저장한다. 스택의 최대 크기를 미리 정해야 하며, top이라는 정수형 인덱스 변수를 사용하여 가장 최근에 추가된 요소의 위치를 추적한다. Push 연산은 top 인덱스를 증가시킨 후 해당 위치에 데이터를 저장하고, Pop 연산은 top 인덱스가 가리키는 데이터를 반환한 후 인덱스를 감소시킨다. 이 방식의 주요 장점은 구현이 간단하고, 캐시 지역성[2]으로 인해 데이터 접근 속도가 매우 빠르다는 점이다. 그러나 스택의 최대 크기가 고정되어 있어, 런타임에 크기를 동적으로 조절하기 어렵다는 단점이 있다.

반면, 연결 리스트를 이용한 구현은 노드들이 메모리 상에 흩어져 저장되고, 각 노드는 데이터와 다음 노드를 가리키는 포인터로 구성된다. 이 경우 top 포인터는 리스트의 헤드(가장 최근에 추가된 노드)를 가리킨다. Push 연산은 새로운 노드를 생성하고, 그 노드의 다음 포인터가 기존의 top 노드를 가리키도록 한 후 top 포인터를 새 노드로 업데이트한다. Pop 연산은 top 포인터가 가리키는 노드의 데이터를 반환하고, top 포인터를 다음 노드로 이동시킨 후 기존 노드를 메모리에서 해제한다. 이 방식의 가장 큰 장점은 메모리가 허용하는 한 스택의 크기에 제한이 없이 동적으로 확장 가능하다는 것이다. 단점은 각 노드가 추가적인 포인터 공간을 차지하여 메모리 오버헤드가 발생하고, 노드들이 메모리 상에 불연속적으로 위치하여 캐시 효율이 배열에 비해 떨어질 수 있다는 점이다.

구현 방식

장점

단점

배열

구현이 간단함, 접근 속도가 매우 빠름(캐시 효율성 높음)

최대 크기가 고정되어 있음(동적 확장 어려움), 미리 큰 메모리를 할당하면 공간 낭비 가능성

연결 리스트

크기에 제한이 없이 동적 확장 가능

노드당 포인터 저장으로 인한 메모리 오버헤드, 캐시 효율성이 상대적으로 낮음

따라서, 스택의 최대 크기를 사전에 예측할 수 있고 빠른 성능이 중요한 경우에는 배열 기반 구현이, 크기를 예측하기 어렵거나 무제한에 가까운 데이터를 처리해야 하는 경우에는 연결 리스트 기반 구현이 선호된다.

3.2. 주요 연산 (Push, Pop, Peek)

LIFO 구조에서 데이터를 조작하는 핵심 동작은 Push, Pop, Peek (또는 Top)의 세 가지 연산으로 구성된다. 이 연산들은 스택이라는 추상 자료형의 표준 인터페이스를 정의하며, 모든 구현은 이 세 동작을 지원해야 한다.

Push 연산은 새로운 데이터 항목을 스택의 가장 위(Top)에 추가한다. 이 연산은 항목을 '밀어 넣는다'는 의미를 가지며, 스택이 가득 찬 상태(배열 구현에서 용량 초과)가 아닌 이상 항상 성공한다. Push 후에는 새로 추가된 항목이 스택의 Top이 된다. Pop 연산은 Push의 반대 동작으로, 현재 스택의 Top에 위치한 항목을 제거하고 그 값을 반환한다. 이 연산은 스택이 비어 있는지 확인해야 하며, 비어 있을 때 Pop을 시도하는 것은 일반적으로 오류(Stack Underflow)를 유발한다. Pop이 성공하면, 그 아래에 있던 항목이 새로운 Top이 된다.

Peek (또는 Top) 연산은 Pop과 달리 데이터를 제거하지 않고, 현재 Top에 있는 항목의 값만을 조회하여 반환한다. 이 연산은 스택의 상태를 변경하지 않으면서 최상위 요소를 확인해야 할 때 사용된다. 예를 들어, 괄호 짝 맞추기 알고리즘에서 현재 스택의 Top을 확인하거나, 연산자 우선순위를 비교할 때 유용하게 활용된다.

이 세 연산의 시간 복잡도는 이상적인 구현에서 모두 O(1), 즉 상수 시간에 수행된다는 특징을 가진다. 이는 데이터의 개수와 관계없이 항상 일정한 시간 내에 연산이 완료됨을 의미하며, LIFO 구조의 가장 큰 장점 중 하나이다.

연산

설명

주의사항

Push

항목을 스택의 Top에 추가한다.

스택이 가득 찼는지 확인해야 한다(배열 구현 시).

Pop

Top 항목을 제거하고 그 값을 반환한다.

스택이 비어 있는지 확인해야 한다(Stack Underflow).

Peek/Top

Top 항목을 제거하지 않고 값만 반환한다.

스택이 비어 있는지 확인해야 한다.

4. 응용 분야

LIFO 구조는 컴퓨터 과학과 소프트웨어 공학의 여러 핵심 영역에서 광범위하게 응용된다. 그 원리는 데이터를 처리해야 하는 순서가 가장 최근에 추가된 항목이 가장 먼저 필요할 때 특히 유용하다.

가장 대표적인 응용은 프로그래밍 언어에서의 함수 호출 관리다. 함수가 호출되면 그 함수의 지역 변수, 매개변수, 그리고 복귀 주소(다음에 실행할 코드 위치) 등의 정보가 스택 메모리 영역에 푸시(push)된다. 함수 실행이 끝나면 이 정보가 팝(pop)되어 호출한 함수로 제어권이 돌아가고, 메모리 공간이 정리된다. 이 메커니즘은 재귀 함수가 자기 자신을 반복적으로 호출할 때도 동일하게 작동하여 각 호출 단계의 상태를 독립적으로 유지한다.

또한, 알고리즘 설계에서도 LIFO는 중요한 역할을 한다. 깊이 우선 탐색(DFS)은 그래프나 트리를 탐색할 때 한 분기를 끝까지 탐색한 후 되돌아와 다른 분기를 탐색하는데, 이때 방문해야 할 다음 노드들을 스택에 저장하여 구현한다. 괄호 검사 알고리즘은 코드나 수식에서 괄호의 짝이 맞는지 확인할 때, 여는 괄호를 스택에 넣고 닫는 괄호를 만나면 스택에서 꺼내는 방식으로 LIFO 원리를 활용한다.

응용 분야

설명

LIFO가 적용되는 이유

스택 메모리 관리

함수 호출 시 실행 컨텍스트 저장

함수 호출과 반환 순서가 정반대이므로

실행 취소(Undo) 기능

사용자 행동 기록

가장 나중에 한 행동을 먼저 취소해야 함

브라우저 뒤로 가기

방문한 페이지 기록

가장 최근에 본 페이지로 돌아가야 함

깊이 우선 탐색(DFS)

그래프 탐색 경로 저장

한 갈래를 끝까지 탐색한 후 되돌아와야 함

4.1. 프로그래밍 (함수 호출, 재귀)

LIFO 구조는 프로그래밍에서 함수 호출과 재귀 알고리즘의 핵심 메커니즘으로 작동한다. 대부분의 프로그래밍 언어는 함수가 호출될 때마다 해당 함수의 실행 컨텍스트(지역 변수, 매개변수, 복귀 주소 등)를 스택 메모리라는 LIFO 방식의 메모리 영역에 저장한다. 함수의 실행이 끝나면 스택의 최상단에서 이 컨텍스트를 제거(Pop)하고, 복귀 주소로 돌아가 이전 함수의 실행을 계속한다. 이 과정은 함수 호출의 중첩과 복귀 순서가 정확히 LIFO 원칙을 따르도록 보장한다.

재귀 함수는 자기 자신을 호출하는 함수로, LIFO 구조 없이는 구현이 불가능하다. 재귀 호출이 발생할 때마다 각 호출의 상태가 스택에 계속해서 쌓인다Push. 재귀의 기저 조건에 도달하면, 가장 최근에 호출된 함수부터 완료되며 스택에서 하나씩 제거된다. 이는 마치 접시를 쌓았다가 위에서부터 하나씩 치우는 것과 같다. 따라서 재귀의 깊이는 사용 가능한 스택 메모리의 크기에 의해 제한을 받는다.

개념

설명

LIFO와의 연관성

함수 호출 스택(Call Stack)

함수 호출 시 실행 정보가 저장되는 메모리 영역

호출 순서와 반대로 복귀하므로 LIFO 구조를 가짐

재귀(Recursion)

함수가 자기 자신을 호출하는 프로그래밍 기법

각 재귀 호출의 상태가 스택에 쌓이고, 해제는 역순으로 이루어짐

스택 오버플로우(Stack Overflow)

스택 메모리 공간을 초과하여 발생하는 오류

재귀 깊이가 너무 깊거나 함수 호출이 과도할 때 발생

이러한 메커니즘 덕분에 프로그래머는 함수 호출의 흐름을 명시적으로 관리하지 않아도 되며, 복잡한 재귀 알고리즘을 직관적으로 작성할 수 있다. 그러나 스택 메모리는 제한된 자원이므로, 무한 재귀나 매우 깊은 호출은 스택 오버플로우 오류를 일으킬 수 있다는 점에 유의해야 한다.

4.2. 메모리 관리 (스택 메모리)

스택 메모리는 LIFO 원칙에 따라 동작하는 메모리 할당 영역이다. 프로그램이 실행될 때, 함수 호출과 지역 변수 할당과 같은 작업을 관리하기 위해 운영체제나 런타임 환경에 의해 할당된다. 각 함수가 호출되면 해당 함수의 지역 변수, 매개변수, 복귀 주소 등의 정보를 담은 스택 프레임이 스택 메모리의 최상위에 쌓인다. 함수 실행이 종료되면 해당 스택 프레임이 제거되며, 이전 함수의 실행 환경으로 복귀한다.

이러한 방식은 메모리 할당과 해제가 매우 빠르고 효율적이다. 메모리 할당은 단순히 스택 포인터를 이동시키는 것으로 이루어지며, 해제는 역순으로 포인터를 되돌리기만 하면 된다. 이는 힙 메모리 관리에서 발생할 수 있는 메모리 단편화 문제를 야기하지 않는다. 또한, 지역 변수에 대한 접근이 캐시 친화적이어서 성능상의 이점을 제공한다.

그러나 스택 메모리의 크기는 일반적으로 제한되어 있으며, 주로 정적이다. 재귀 함수의 깊이가 지나치게 깊거나 큰 지역 변수를 할당할 경우 스택 오버플로우가 발생하여 프로그램이 비정상 종료될 수 있다. 또한, 스택에 할당된 변수의 수명은 해당 범위(함수나 블록)에 국한되므로, 함수 호출이 끝난 후에도 데이터를 유지해야 하는 경우에는 적합하지 않다.

특징

설명

할당/해제 방식

자동 (컴파일러/런타임에 의해 관리)

관리 비용

낮음

접근 속도

매우 빠름

메모리 단편화

발생하지 않음

변수 수명

범위(스코프) 기반

주요 용도

함수 호출, 지역 변수, 매개변수

4.3. 알고리즘 (DFS, 괄호 검사)

LIFO 구조는 여러 알고리즘의 핵심 메커니즘으로 활용된다. 그 대표적인 예가 깊이 우선 탐색(DFS)이다. DFS는 그래프나 트리의 한 노드를 탐색할 때, 가능한 깊게 내려가며 탐색하는 알고리즘이다. 이 과정에서 방문할 노드들을 스택에 저장하고, 가장 마지막에 추가된 노드(최상단 노드)를 꺼내어 탐색을 진행한다[3]. 이는 LIFO 원칙에 따라 현재 탐색 경로를 역추적하며 다른 가지로 이동할 수 있게 해준다.

또 다른 주요 응용은 괄호 검사나 태그 짝 맞추기와 같은 구문 분석이다. 예를 들어 수식이나 코드에서 괄호 (, ), {, }, [, ]의 쌍이 올바르게 닫혔는지 확인할 때 스택을 사용한다. 알고리즘은 다음과 같이 동작한다.

단계

동작

1

문자열을 왼쪽부터 순회한다.

2

열린 괄호((, {, [)를 만나면 스택에 push한다.

3

닫힌 괄호(), }, ])를 만나면 스택의 top을 pop하여 짝이 맞는지 비교한다.

4

순회 종료 후 스택이 비어 있어야 모든 괄호의 짝이 맞는 것이다.

이 방법은 중첩된 괄호 구조를 처리하는 데 매우 효율적이다. LIFO 원리는 가장 나중에 열린 괄호가 가장 먼저 닫혀야 한다는 규칙과 정확히 일치하기 때문이다. 이와 유사한 원리로 HTML/XML 태그의 유효성 검사나 프로그램의 들여쓰기 구조 분석에도 적용된다.

5. 장단점

LIFO 구조의 가장 큰 장점은 자료구조의 구현과 관리가 매우 간단하다는 점이다. 데이터의 추가와 제거가 항상 한쪽 끝(스택의 top)에서만 일어나므로, 포인터나 인덱스 하나만으로 모든 연산을 효율적으로 처리할 수 있다. 이로 인해 Push와 Pop 연산의 시간 복잡도는 O(1)로 상수 시간에 수행된다[4]. 또한, 구조가 단순하여 메모리를 효율적으로 사용할 수 있다.

반면, LIFO의 주요 단점은 데이터 접근에 제약이 많다는 것이다. 가장 최근에 삽입된 데이터만을 바로 접근할 수 있으며, 중간에 위치한 데이터에 접근하려면 그 위에 있는 모든 데이터를 제거해야 한다. 이는 특정 데이터를 검색하거나 수정해야 하는 상황에서는 매우 비효율적이다. 또한, 스택의 크기가 고정된 배열로 구현된 경우, 데이터가 가득 차면 더 이상 삽입할 수 없는 스택 오버플로우 문제가 발생할 수 있다.

장점

단점

구현이 간단하고 직관적이다.

중간 데이터에 대한 직접 접근이 불가능하다.

데이터 삽입/삭제 속도가 매우 빠르다(O(1)).

특정 데이터 검색이 비효율적이다.

메모리 사용이 효율적이다.

고정 크기 구현 시 저장 공간의 제약을 받는다.

따라서 LIFO는 데이터의 임시 저장과 후입선출 순서가 중요한 콜 스택이나 실행 취소 기능 등 특정 문제에 매우 적합하지만, 일반적인 데이터 저장 및 조회 용도로는 제한적으로 사용된다.

5.1. 장점

LIFO 구조의 가장 큰 장점은 데이터의 추가와 삭제가 매우 빠르다는 점이다. 스택의 Push와 Pop 연산은 모두 시간 복잡도 O(1)로, 상수 시간 내에 처리된다. 이는 데이터가 저장된 위치(보통 스택 포인터가 가리키는 최상단)만 관리하면 되기 때문이다. 따라서 대량의 데이터를 처리할 때도 삽입과 삭제에 대한 성능 저하가 거의 없다.

구현이 단순하고 직관적이라는 점도 주요 장점이다. 기본적인 배열이나 연결 리스트만으로도 쉽게 구현할 수 있으며, 후입선출이라는 동작 원리가 명확하여 프로그래머가 동작을 예측하고 디버깅하기 쉽다. 이 단순성은 스택 메모리 관리나 함수 호출과 같은 시스템 핵심 기능에 안정적으로 적용될 수 있는 기반이 된다.

특정 문제를 해결하는 데 매우 효율적인 모델을 제공한다. 예를 들어, DFS 알고리즘에서 경로를 추적하거나, 재귀 함수 호출의 복귀 주소를 관리하며, 프로그램 코드의 괄호 검사를 수행하는 데 있어 LIFO 방식은 자연스럽고 최적의 접근법이 된다. 또한 실행 취소나 브라우저 뒤로 가기와 같이 가장 최근의 상태로 순차적으로 돌아가야 하는 기능을 구현하는 데 필수적이다.

장점

설명

연산 속도

Push와 Pop 연산이 O(1)의 상수 시간 복잡도를 가져 매우 빠르다.

구현 용이성

자료구조가 단순하여 배열이나 연결 리스트로 쉽게 구현 가능하다.

자원 관리 효율성

스택 메모리 할당/해제가 빠르고 예측 가능하여 시스템 자원 관리에 효율적이다.

특정 문제 해결 적합성

역순 접근이 필요한 알고리즘(DFS, 실행 취소 등)에 자연스럽게 적용된다.

5.2. 단점

LIFO 구조는 데이터를 가장 최근에 추가한 순서대로만 접근할 수 있다는 근본적인 제약을 가집니다. 이로 인해 가장 먼저 저장된 데이터에 접근하려면 그 위에 쌓인 모든 데이터를 제거해야 하므로, 특정 데이터에 대한 직접적인 접근이 매우 비효율적입니다. 이러한 특성은 FIFO 구조에 비해 데이터 탐색이나 중간 요소 조회가 필요한 상황에서는 명확한 한계로 작용합니다.

또한, 스택 오버플로와 같은 문제가 발생할 수 있습니다. 스택의 크기가 제한된 환경에서 너무 많은 데이터를 Push 연산으로 추가하면, 할당된 메모리 공간을 초과하여 프로그램이 비정상적으로 종료되거나 보안 취약점이 발생할 수 있습니다. 반대로, 비어 있는 스택에서 Pop 연산을 시도하는 스택 언더플로 역시 오류를 유발합니다. 따라서 스택의 크기를 사전에 관리하거나 동적 할당을 통해 적절히 제어해야 합니다.

다음 표는 LIFO의 주요 단점을 정리한 것입니다.

단점

설명

임의 접근 불가

스택의 중간이나 바닥에 있는 데이터에 직접 접근할 수 없으며, 접근을 위해서는 상위 데이터를 모두 제거해야 함

제한된 용량

고정된 크기의 배열로 구현 시 스택 오버플로우가 발생할 위험이 있음

데이터 순서 제약

데이터가 저장된 순서와 반대 방향으로만 처리할 수 있어, 선입선출이 필요한 상황에는 부적합함

잘못된 사용 시 오류

빈 스택에서 Pop을 시도하거나, 포인터 관리 실패 시 예측 불가능한 동작을 초래할 수 있음

마지막으로, LIFO는 특정 문제 해결에 최적화되어 있어 그 적용 범위가 제한적입니다. 예를 들어, 대기열 관리나 버퍼처럼 순차적으로 처리해야 하는 작업에는 적합하지 않습니다. 이는 LIFO가 가진 구조적 특성에서 비롯된 본질적인 단점으로, 사용 전에 문제의 요구사항을 신중히 평가해야 할 필요성을 시사합니다.

6. FIFO와의 비교

LIFO와 FIFO는 데이터를 처리하는 순서를 정의하는 두 가지 상반된 원리이다. LIFO는 'Last In, First Out'의 약자로, 가장 나중에 들어온 데이터가 가장 먼저 나가는 방식을 의미한다. 반대로 FIFO는 'First In, First Out'의 약자로, 가장 먼저 들어온 데이터가 가장 먼저 나가는 방식을 의미한다. 이 두 방식은 각각 다른 자료구조를 통해 구현되며, 서로 다른 문제 해결에 적합한 특성을 지닌다.

주요 차이점은 다음과 같이 표로 정리할 수 있다.

비교 항목

LIFO (Last In, First Out)

FIFO (First In, First Out)

대표 자료구조

스택(Stack)

큐(Queue)

삽입 연산

Push (상단에 추가)

Enqueue (Rear/뒤쪽에 추가)

삭제 연산

Pop (상단에서 제거)

Dequeue (Front/앞쪽에서 제거)

접근 가능 데이터

가장 최근에 추가된 항목만 (Top)

가장 오래된 항목과 가장 최근 항목 모두 (Front, Rear)

동작 비유

접시 쌓기, 책상 위 서류 더미

줄 서기, 콘서트 티켓 매표소

주요 응용 분야

함수 호출 스택, 실행 취소(Undo), 깊이 우선 탐색(DFS)

작업 스케줄링, 프린터 대기열, 너비 우선 탐색(BFS)

이러한 구조적 차이로 인해 두 방식은 서로 다른 장단점을 가진다. LIFO는 최근 데이터에 대한 접근이 매우 빠르고 구현이 단순하다는 장점이 있지만, 중간에 있는 데이터에 직접 접근하기 어렵다는 제약이 있다. 반면 FIFO는 데이터가 들어온 순서를 공정하게 유지할 수 있어 대기열 관리에 적합하지만, 특정 데이터를 찾기 위해서는 앞의 모든 데이터를 순차적으로 처리해야 할 수 있다. 따라서 문제의 성격에 따라 LIFO를 구현한 스택과 FIFO를 구현한 큐 중 적절한 자료구조를 선택하여 사용한다.

7. 실제 사례

실행 취소(Undo) 기능은 LIFO 원리가 적용되는 대표적인 사례이다. 대부분의 문서 편집기나 그래픽 소프트웨어는 사용자가 수행한 작업(예: 텍스트 입력, 삭제, 서식 변경)을 순서대로 기록한다. 이 기록은 스택 구조로 관리되며, 가장 최근에 수행한 작업이 스택의 맨 위에 위치한다. 사용자가 실행 취소 명령을 내리면, 소프트웨어는 스택의 맨 위에서 가장 최근 작업을 꺼내어(Pop) 그 작업을 반대로 수행하여 이전 상태로 되돌린다. 반복적인 실행 취소는 스택에 쌓인 순서의 역순으로, 즉 가장 나중에 한 작업부터 차례대로 되돌리게 된다.

웹 브라우저의 '뒤로 가기'(Back) 기능도 유사한 LIFO 메커니즘을 사용한다. 사용자가 웹 페이지를 방문할 때마다 그 URL 주소는 방문 기록 스택에 차곡차곡 쌓인다(Push). 사용자가 뒤로 가기 버튼을 클릭하면, 브라우저는 이 스택의 맨 위에서 가장 최근에 방문한 페이지를 꺼내고(Pop), 그 바로 이전에 저장된 페이지로 사용자를 이동시킨다. 앞으로 가기(Forward) 기능은 일반적으로 별도의 스택을 사용하여 뒤로 가기에서 꺼낸 페이지들을 다시 저장하는 방식으로 구현된다[5].

이 외에도 LIFO는 다양한 소프트웨어와 시스템에서 발견된다. 예를 들어, 워드 프로세서의 텍스트 서식 변경 기록, IDE(통합 개발 환경)의 코드 탐색 경로, 그리고 복잡한 작업을 단계적으로 수행하다가 문제 발생 시 이전 단계로 롤백(Rollback)해야 하는 데이터 처리 시스템 등에서 그 원리가 활용된다. 이러한 구현들은 모두 '가장 최근에 추가된 항목이 가장 먼저 처리되어야 한다'는 LIFO의 핵심 원리를 공유한다.

7.1. 실행 취소(Undo) 기능

실행 취소 기능은 소프트웨어에서 사용자가 수행한 작업을 역순으로 되돌릴 수 있게 해주는 일반적인 기능이다. 이 기능은 LIFO 방식으로 동작하는 스택 자료구조를 활용하여 구현되는 경우가 많다. 사용자가 텍스트 편집, 그림 그리기, 객체 이동 등의 작업을 수행할 때마다 그 변경 사항(또는 변경 전 상태)이 하나의 명령으로 간주되어 스택에 차례대로 쌓인다.

사용자가 실행 취소를 요청하면, 스택의 최상위에 있는, 즉 가장 최근에 수행된 명령이 Pop 연산을 통해 제거되며, 해당 명령의 효과를 반대로 적용하여 이전 상태로 복원한다. 예를 들어, 문서 편집기에서 글자를 입력하면 그 입력 동작이 스택에 저장되고, 실행 취소를 누르면 가장 마지막에 입력된 글자가 제거된다. 연속적으로 실행 취소를 하면 스택에 저장된 순서의 반대, 즉 작업을 수행한 순서의 역순으로 상태가 되돌아간다.

이러한 구현 방식은 직관적이고 관리가 간단하다는 장점이 있지만, 모든 작업 기록을 메모리에 보관해야 하므로 많은 작업을 수행한 경우 메모리 사용량이 늘어날 수 있다. 또한, 일반적인 LIFO 방식의 실행 취소는 '다시 실행' 기능을 위해 별도의 Redo 스택을 함께 운용하는 경우가 많다. 실행 취소를 하면 원본 명령이 실행 취소 스택에서 제거되어 다시 실행 스택으로 이동하는 식이다.

특징

설명

작동 원리

명령을 수행한 순서대로 스택에 저장(Push), 취소 시 역순으로 제거(Pop)하여 상태 복원

데이터 구조

주로 스택 또는 두 개의 스택(Undo/Redo)을 사용

복잡도

명령 추가와 취소 연산이 일반적으로 O(1)의 시간 복잡도를 가짐

제한 사항

스택 크기에 제한이 있을 수 있으며, 모든 작업이 원자적으로 취소 가능해야 함

실행 취소 기능은 문서 편집기, 그래픽 소프트웨어, 통합 개발 환경 등 사용자 상호작용이 중요한 거의 모든 응용 프로그램의 핵심 기능으로 자리 잡았다. 이는 사용자가 실수를 쉽게 교정할 수 있게 함으로써 소프트웨어의 사용성을 크게 향상시킨다.

7.2. 브라우저 뒤로 가기

웹 브라우저의 '뒤로 가기' 기능은 LIFO 원리를 활용한 대표적인 사례이다. 사용자가 웹 페이지를 방문할 때마다 그 URL은 방문 기록 스택에 순차적으로 쌓인다. '뒤로 가기' 버튼을 누르면 가장 최근에 추가된, 즉 스택의 맨 위에 있는 항목이 제거되며(pop), 그 직전에 방문한 페이지로 이동한다.

이 구조는 단순히 한 단계 뒤로 가는 것뿐만 아니라, 연속적인 뒤로 가기 동작을 가능하게 한다. 사용자가 A 페이지에서 B, C, D 페이지를 차례로 방문했다면, 방문 기록 스택은 [A, B, C, D]와 같이 구성된다. 첫 번째 '뒤로 가기'는 D를 꺼내 C 페이지로 이동시키고, 스택은 [A, B, C]가 된다. 이후 '뒤로 가기'를 계속하면 C, B가 순차적으로 제거되며 최종적으로 A 페이지에 도달한다.

동작

방문 기록 스택 상태

현재 페이지

설명

초기 상태

[홈]

홈

-

페이지 A 방문

[홈, A]

A

A가 스택에 push됨

페이지 B 방문

[홈, A, B]

B

B가 push됨

'뒤로 가기' 클릭

[홈, A]

A

가장 최근 항목 B가 pop됨

다시 '뒤로 가기' 클릭

[홈]

홈

다음 항목 A가 pop됨

'앞으로 가기' 기능은 일반적으로 '뒤로 가기' 스택에서 꺼낸 항목들을 임시로 보관하는 또 다른 스택을 활용하여 구현한다[6]. 이렇게 함으로써 사용자는 방문 기록을 양방향으로 탐색할 수 있는 편리한 경험을 제공받는다.

8. 관련 문서

  • Wikipedia - LIFO (컴퓨터 과학)

  • 나무위키 - LIFO

  • Techopedia - What is Last In, First Out (LIFO)?

  • GeeksforGeeks - Stack Data Structure

  • MDN Web Docs - JavaScript Call Stack

  • Oracle Java Documentation - Class Stack

  • Microsoft Learn - Stack<T> Class

리비전 정보

버전r1
수정일2026.02.14 23:09
편집자unisquads
편집 요약AI 자동 생성