💡 스택(Stack)은 한 쪽 끝에서만 제한적으로 접근하여 데이터를 넣고 뺄 수 있는 후입선출(Last-In-First-Out) 형태의 선형 자료구조이다.
스택(Stack)은 LIFO(Last-In-First-Out)/FILO(First-In-Last-Out) 순서를 따른다.
기본적으로 stack 클래스는 내부에서 최상위 타입 배열인 Object[] 배열을 사용하여 데이터를 관리하고 있다.
→ 스택은 시간 순서에 따라 데이터가 쌓이게 되므로 가장 마지막에 삽입된 데이터가 가장 먼저 삭제된다는 특징을 가진다.
스택은 기본적으로 후입선출(나중에 들어온 데이터가 가장 먼저 나가는) 구조로 이루어져 있다.
위의 그림을 보면 가장 먼저 들어온 a 데이터가 가장 마지막에 쌓여있고 가장 나중에 들어온 c 데이터가 가장 위에 놓여져 있다. 데이터를 넣고 빼는 입구가 하나뿐인 스택은 가장 위에 쌓인 데이터를 먼저 꺼내도록 작동한다.
✔️ 가장 최근에 스택에 추가한 항목이 가장 먼저 제거될 항목
스택은 아래 그림과 같은 구조로 이루어져 있다.
Bottom: 가장 밑에 있는 데이터 또는 인덱스
Top: 가장 위에 있는 데이터 또는 인덱스
Capacity: 스택에 담을 수 있는 데이터의 총 용량
Size: 현재 스택에 담겨져있는 데이터의 개수
문제의 종류에 따라 배열보다 스택에 데이터를 저장하는 것이 더 적합한 방법일 수 있다.
스택은 연결리스트로 구현할 수 있다. 연결리스트의 같은 방향에서 아이템을 추가하고 삭제하도록 구현한다.
class stack:
def __init__(self): # stack 객체 생성
self.items = []
def push(self, data): # stack 데이터 추가 append
self.items.append(data)
def pop(self):
pop_object = None
if self.isEmpty():
print("Stack is Empty")
else:
pop_object = self.items.pop()
return pop_object # stack의 가장 마지막 데이터를 삭제하고 return pop()
def peek(self):
if self.isEmpty():
print("Stack is Empty")
else:
return self.top[-1]
return top_object # stack의 가장 마지맏 데이터 return
def isEmpty(self):
is_empty = False
if len(self.items) == 0:
is_empty = True
return is_empty # stack이 비었는지 확인하고 boolean 값으로 반환
💡 스택에 데이터를 추가하는 작업은 push()로 이루어진다.
스택에 데이터를 추가하면 가장 마지막 부분(최상단)에 추가된다. 스택에 데이터를 추가하는 push 작업은 인덱스를 증가하면서 이루어진다.
array = list()
def append(data):
array.append(data)
append("A")
append("B")
append("C")
💡 스택에 데이터를 삭제하는 작업은 pop()으로 이루어진다.
스택에 데이터를 삭제하는 작업은 가장 위에 있는 (가장 마지막에 추가된 데이터) 데이터를 제거한다.
데이터 제거 시 중요한 점은 스택이 비어있어 삭제할 데이터가 없는 경우이다.
array = list()
def pop():
data = array[-1]
def array[-1]
return data
pop() # C
pop() # B
pop() # A
💡 peek()은 가장 상단에 있는 데이터를 삭제하지 않고 확인만 하고 싶을 때 사용하는 메서드이다.
스택의 가장 위에 있는 항목을 반환하며 pop()에서 삭제 과정만 없는 것이 peek()이다.
💡 isEmpty() 는 Stack이 비어있는지 확인하는 메서드이다.
스택이 비어 있으면 True, 데이터가 있으면 False를 반환한다.
💡 스택은 상수 시간에 i번째 항목에 접근할 수 없다. 하지만 스택에서 데이터를 추가하거나 삭제하는 연산은 상수 시간에 가능하다.
스택의 삽입이나 삭제 시 맨 위의 데이터를 삭제하기 때문에 시간복잡도는 늘 O(1)이다. 하지만 특정 데이터를 찾을 때는 데이터를 찾을 때까지 순차적으로 수행해야 하므로 O(n) 시간복잡도를 갖는다.