선입후출(First In Last Out) 구조 또는 후입선출(Last In First Out) 구조
스택 예제
stack = []
# 삽입(5) - 삽입(2) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제()
stack.append(5)
stack.append(2)
stack.append(3)
stack.append(7)
stack.pop()
stack.append(1)
stack.append(4)
stack.pop()
print(stack) # 최하단원소부터 출력
print(stack[::-1] # 최상단 원소부터 출력
[5, 2, 3, 1]
[1, 3, 2, 5]
선입선출(First In First Out) 구조
큐 예제
from collections import deque
# 큐(Queue) 구현을 위해 deque 라이브러리 사용
queue = deque()
# 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제()
queue.append(5)
queue.append(2)
queue.append(3)
queue.append(7)
queue.popleft()
queue.append(1)
queue.append(3)
queue.popleft()
print(queue) # 먼저 들어온 순서대로 출력
queue.reverse() # 다음 출력을 위해 역순으로 바꾸기
print(queue) # 나중에들어온 원소부터 출력
deque([3, 7, 1, 4])
deque([4, 1, 7, 3])
자기 자신을 다시 호출하는 함수
재귀 함수 예제
def recursive_function() :
print('재귀 함수를 호출합니다.')
recursive_function()
recursive_function()
recursionerror maximum recursion depth exceeded while pickling an object
재귀 함수를 문제 풀이에서 사용할 때는 재귀 함수가 언제 끝날지, 종료 조건을 꼭 명시해야 한다.
재귀 함수 종료 예제
def recursive_function(i) :
# 100번째 출력했을 때 종료되도록 종료 조건 명시
if i == 100 :
return
print(i, '번째 재귀 함수에서', 'i + 1, '번째 재귀 함수를 호출합니다.
recursive_function(i + 1)
print(i, '번째 재귀 함수를 종료합니다.')
recursive_function(1)
컴퓨터 내부에서 재귀 함수의 수행은 스택 자료구조를 이용
함수를 계속 호출했을 때 가장 마지막에 호출한 함수가 먼저 수행을 끝내야 그 앞의 함수 호출이 종료되기 때문이다.
컴퓨터의 구조 측면에서 보자면 연속해서 호출되는 함수는 메인 메모리의 스택 공간에 적재되므로 재귀 함수는 스택 자료구조와 같다는 말은 틀린 말이 아니다.
재귀함수는 내부적으로 스택 자료구조와 동일하다
따라서 스택 자료구조를 활용해야 하는 상당수 알고리즘은 재귀 함수를 이용해서 간편하게 구현될 수 있다. DFS가 대표적인 예이다.
재귀 함수를 이용하는 대표적 예제 팩토리얼(Factorial)
2가지 방식으로 구현한 팩토리얼 예제
# 반복적으로 구현한 n!
def factorial_iterative(n) :
result = 1
# 1부터 n까지의 수를 차례대로 곱하기
for i in range(1, n + 1) :
result *= i
return result
# 재귀적으로 구현한 n!
def factorial_recursive(n) :
if <= 1 : # n이 1 이하인 경우 1을 반환
return 1
# n! = n * (n -1) !를 그대로 코드로 작성하기
return n * factorial_recursive(n - 1)
# 각각의 방식으로 구현한 n! 출력(n = 5)
print('반복적으로 구현 : ', factorial_iterative(5))
print('재귀적으로 구현 : ', factorial_recursive(5))
반복적으로 구현 : 120
재귀적으로 구현 : 120
출처 : 이것이 코딩테스트다 with 파이썬