스택 (Stack)
스택은 후입선출(LIFO : Last In First Out)로 처리되는 자료구조이다. 즉 스택의 가장 마지막에 들어간 요소가 가장 처음으로 꺼내진다.
다시말해 데이터의 삽입과 삭제가 데이터의 한쪽 끝에서만 일어난다.
![[자료구조] Stack(스택) - Java, Python - 스택 (Stack) [자료구조] Stack(스택) - Java, Python - 스택 (Stack)](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
위와 같은 구조에서 우리는 크게 두가지 행동을 할 수 있다.
- 새로운 접시를 추가하는것.
- 맨 위의 접시를 제거하는것.
만약 새로운 접시를 맨 아래에 놓거나, 맨 위가 아닌 특정 위치에 놓고싶다면 놓고싶은 위치를 기준으로 위에 있는 접시들을 모두 제거한 후 추가해야한다.
이것이 바로 스택이 작동하는 방식이다.
후입선출(LIFO : Last In First Out)의 원리
Stack 위에 어떤 원소를 집어넣는것을 Push 라고 하고, 원소를 제거하는것을 Pop 이라고 한다.
![[자료구조] Stack(스택) - Java, Python - 후입선출(LIFO : Last In First Out)의 원리 [자료구조] Stack(스택) - Java, Python - 후입선출(LIFO : Last In First Out)의 원리](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
위에서 원소 3은 제일 마지막으로 스택에 추가되었지만, 제거될때 제일 먼저 제거되었다.
이것이 바로 후입선출(LIFO : Last In First Out)의 원리이다.
C, C++, Java, Python 또는 C#과 같은 다양한 언어들로 스택을 구현할 수 있지만, 성능은 거의 동일하다.
스택의 기본적인 명령어
- Push : 스택의 최상단에 원소 추가
- Pop : 스택의 최상단에 위치한 원소 제거
- IsEmpty : 스택이 비어있는지 체크
- IsFull : 스택이 가득 찼는지 확인
- Peek : 스택의 최상단에 위치한 원소 값(value)를 읽어옴(제거하지 않는다)
스택의 동작방식
스택은 다음과 같은 방식으로 진행된다.
1. TOP 이라는 포인터를 생성해 스택의 최상단에 위치한 원소를 가르키도록 한다.
2. 스택이 초기화(Initializing)되었을 때, TOP 의 value 를 -1로 설정해 스택이 비었을 때 TOP == -1 을 사용하여 체크할 수 있도록 한다.
3. 원소를 push 할때마다, TOP 의 vaule를 증가시키고, TOP이 가르키는 위치에 새로운 원소를 추가한다.
4. 원소를 pop 할때마다, TOP 이 가르키는 위치의 원소를 return 하고, TOP 의 value 를 감소시킨다.
5. push 를 하기 전, 스택이 가득찼는지 체크한다.
6. pop 을 하기 전, 스택이 비어있는지 체크한다.
![[자료구조] Stack(스택) - Java, Python - 스택의 동작방식 [자료구조] Stack(스택) - Java, Python - 스택의 동작방식](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
스택 구현
# Python
# stack 생성
def create_stack():
stack = []
return stack
# 비어있는 stack 생성
def check_empty(stack):
return len(stack) == 0
# stack에 원소 추가 (push)
def push(stack, item):
stack.append(item)
print("pushed item: " + item)
# stack의 원소 제거 (pop)
def pop(stack):
if (check_empty(stack)):
return "stack is empty"
return stack.pop()
stack = create_stack()
push(stack, str(1))
push(stack, str(2))
push(stack, str(3))
push(stack, str(4))
print("popped item: " + pop(stack))
print("stack after popping an element: " + str(stack))
// Java
class Stack {
private int arr[];
private int top;
private int capacity; //stack의 size(용량)
// stack 생성
Stack(int size) {
arr = new int[size];
capacity = size;
top = -1;
}
// stack에 원소 추가 (push)
public void push(int x) {
//제일 먼저 stack이 가득찼는지 체크!
if (isFull()) {
System.out.println("OverFlow\nProgram Terminated\n");
System.exit(1);
}
System.out.println("Inserting " + x);
arr[++top] = x;
}
// stack의 원소 제거 (pop)
public int pop() {
// 항상 stack이 비어있는지 체크
if (isEmpty()) {
System.out.println("STACK EMPTY");
System.exit(1);
}
// pointer "top" 의 값을 감소시키는거라 실제 바로바로 원소를 날려버리는건 아니다.
return arr[top--];
}
// stack의 size를 return 하는 Utility function
public int size() {
return top + 1;
}
// stack이 비었는지 체크하는 function
public Boolean isEmpty() {
//스택이 비어있다면 top의 value는 -1이다.
return top == -1;
}
// stack이 가득찼는지 체크하는 function
public Boolean isFull() {
// stack이 가득찼다면, top의 value는 size - 1 이다. 즉 포인터가 최대치 부분을 가르키고 있다는것.
return top == capacity - 1;
}
public void printStack() {
for (int i = 0; i <= top; i++) {
System.out.println(arr[i]);
}
}
public static void main(String[] args) {
Stack stack = new Stack(5);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.pop();
System.out.println("\nAfter popping out");
stack.printStack();
}
}
스택의 시간복잡도
array 기반의 push 와 pop 을 사용하는 stack은 O(1) 의 시간복잡도를 가진다.
스택을 사용해보자
스택은 구현하는데 있어 굉장히 간단하지만, 굉장히 효율적이다. 스택의 일반적인 용도는 다음과 같다.
- 문자열 뒤집기 : 후입선출(LIFO : Last In First Out)때문에 문자열을 스택에 넣고 (push) 다시 빼면 (pop) 문자열이 역순으로 나오게된다.
- 컴파일러 내부 연산 : 컴파일러는 스택을 사용하여 2 + 4 / 5 * (7 - 9 ) 와 같은 식을 전위 또는 후위연산(prefix or postfix)식으로 변환하여 계산한다.
- 브라우저 URL 체크 : 브라우저의 뒤로가기 버튼 또는 앞으로 가기 버튼을 누를 때 마다, 스택의 TOP(pointer) value가 감소 또는 증가하며 저장되어있는 URL로 이동한다. 새로운 페이지를 방문할 때 마다, 현재 URL이 스택의 최상단에 추가된다(push) 그리고 뒤로가기 버튼을 누르면 현재 URL이 스택에서 제거(pop)되고, 이전 URL로 이동하게된다.
'ETC > 자료구조 이론' 카테고리의 다른 글
[JAVA] 다이나믹 프로그래밍 (Dynamic Programming) (0) | 2022.09.19 |
---|---|
[자료구조] Queue(큐) - Java, Python (0) | 2021.08.16 |
[JAVA] 순차탐색(Sequential Search), 이진탐색(Binary Search) (0) | 2020.09.08 |
댓글