Featured image of post Stack (Data Structure)

Stack (Data Structure)

About stack

Stack

스택은 한쪽 방향으로만 데이터를 저장하고 추출하는 형식의 자료 구조이다. 가장 최근에 저장된 값이 가장 먼저 추출되는 방식을 사용한다 (LIFO[Last In First Out] or FILO[First In Last Out])


스택의 연산

stack


  • pop : 스택에서 가장 마지막에 있는 데이터를 제거한다 (삭제)
  • push : 데이터를 가장 마지막 부분에 추가한다 (삽입)
  • peek : 가장 마지막 부분에 있는 데이터를 반환한다 (읽기)
  • isEmpty : 스택이 비어 있을 때 true를 반환한다

Stack overflow, underflow

1
2
Stack overflow는 스택의 최대길이까지 데이터가 차있을 때 스택에 데이터를 추가하려고 할 때 발생하는 에러 
Stack underflow는 스택에 아무것도 없을 때 데이터를 불러오려고 시도하면 발생하는 에러 

예시

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Stack(object):
    def __init__(self, limit = 5):
        self.stack = []
        self.limit = limit

    def __str__(self):
        return ' '.join([str(i) for i in self.stack])

    def push(self, data):
        # 스택의 최대길이에 도달하면 stack overflow 출력 
        if len(self.stack) >= self.limit:
            print('Stack overflow')
        else:
            self.stack.append(data)
        
    def pop(self):
        # 스택이 비어있으면 stack stack underflow 출력 
        if len(self.stack) <= 0:
            print('Stack underflow')
        else:
            return self.stack.pop()
        
    def peek(self):
        if len(self.stack) <= 0:
            print('Stack underflow')
        else:
            return self.stack[len(self.stack) - 1]

스택의 장단점

장점

  • 구조가 단순해서 구현하기 쉽다
  • 데이터의 저장, 읽기 속도가 빠르다

단점

  • 데이터 최대 갯수를 정해야 한다 (파이썬의 경우 재귀함수 호출은 1000번까지 가능)
  • 저장공간이 비효율적이다 (최대 갯수를 정해야 하기 때문에)
  • 데이터의 삽입, 삭제가 비효율적이다

스택의 활용

  • 재귀 알고리즘
  • DFS 알고리즘
  • 작업 실행 취소와 같은 역추적 작업이 필요할 때
  • 괄호 검사, 후위 연산법, 문자열 역순 출력 등

파이썬으로 구현하기

Factorial과 stack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def facto(n):
    # stack 할당 
    stack = []
    
    # n부터 1까지 수행 
    while n > 0:
        # n부터 1까지 stack에 추가 
        stack.append(n)
        n -= 1 
    result = 1 
    
    # stack에 있는 것을 1부터 뽑아서 n까지 누적 곱 수행 (가장 마지막에 넣은 값부터 뽑기 때문에 stack처럼 작동한다)
    while stack: 
        result *= stack.pop()
    return result

facto(5)
: 120 # 1*2*3*4*5 


📌 파이썬 재귀의 한계 

def recur(n):
    print(n)
    if n == 2968:
        return "limit"
    if n == 2969:
        return "exceed"
    return recur(n+1) 

recur(1) 
: 1
  2
  3 
  ...
  2964
  2965
  2966
  2967
  2968
  'limit'

# 파이썬의 재귀호출은 2968이 최대이다 

# 단, 재귀의 한계를 늘릴 수는 있다 

import sys 
sys.setrecursionlimit(4000)

recur(1) 
: 1
  2
  3 
  ...
  3964
  3965
  3966
  3967
  3968
  RecursionError 

Array와 Stack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Stack: 
    def __init__(self): 
        # 데이터 저장을 위한 리스트 준비 
        self.data = [] 
		
		def push(self, val): 
        # 가장 마지막에 값 추가 
        self.data.append(val) 
		
    def pop(self): 
        try: 
		        # 데이터가 있으면 가장 마지막 값 읽기 
		        return self.data.pop() 
		    except IndexError: 
		        # 데이터가 없으면 인덱스에러 발생
            print("Stack is empty") 
		
    def __len__(self): 
		    # len()로 호출하면 stack의 data 수 반환 
		    return len(self.data) 
		
    def isEmpty(self): 
        # 스택이 현재 비어 있는지 확인 
		    return self.__len__() == 0

Reference

1
2
3
4
1. https://cotak.tistory.com/69
2. https://ratsgo.github.io/data%20structure&algorithm/2017/10/11/stack/
3. https://data-marketing-bk.tistory.com/15
4. https://medium.com/@jch9537/stack-queue-linked-list-63ff4d54ec7d
Hugo로 만듦
JimmyStack 테마 사용 중