- 스택, 큐 모두 '선형' 자료구조이다.
- 추가적으로, 대표적 비선형 자료구조에는 '트리', '그래프'가 있다.
먼저, 스택을 알아보도록 한다.
- "후입선출" 구조로, 가장 나중에 추가된 자료가 가장 먼저 제거된다.
-> 즉, 한쪽 끝에서만 자료를 넣거나 뺄 수 있다.- 제한적으로 접근 가능한 자료구조이다.
- 스택은 의존관계가 있는 상태를 처리한다.
- 만약 어떤 일보다 더 먼저 처리되어야 하는 일이 있다면 스택에 저장할 수 있다.
👩💻 콜스택
👩💻 재귀함수
👉 파이썬의 append, pop 연산으로 리스트를 통해 구현할 수 있다.
👀 스택은 아래의 두 가지 방법으로 구현이 가능하다.
1. 배열로 구현
class Stack:
def __init__(self):
self.stack = []
def isEmpty(self):
if len(self.stack) == 0:
return True
else:
return False
def push(self, data):
self.stack.append(data)
def pop(self):
if self.isEmpty():
return "Stack is empty"
else:
return self.stack.pop()
def top(self):
if self.isEmpty():
return "Stack is empty"
else:
return self.stack[-1]
2. 연결리스트로 구현(Singly Linked List)
# Singly Linked Stack
class Node:
def __init__(self, data):
self.data = data
self.next = None
class SinglyLinkedStack:
def __init__(self):
self.head = None
def isEmpty(self):
if self.head is None:
return True
else:
return False
def pop(self):
if self.isEmpty():
return "Stack is Empty"
else:
popped = self.head.data
self.head = self.head.next
return popped
def push(self, data):
new_node = Node(data)
# push된 데이터는 head를 가리킨다.
new_node.next = self.head
# head는 top 데이터가 된다.
self.head = new_node
def top(self):
if self.isEmpty():
return "Stack is Empty"
else:
return self.head.data
이제 큐를 알아보자!
- "선입선출" 구조로, 가장 처음에 추가된 자료가 가장 먼저 제거된다.
- 입구와 출구가 각각 반대쪽 끝에 존재하는 자료구조이다.
👩💻 스케줄링
👉 만약 rear가 가리키는 인덱스가 배열의 크기를 초과하게 되면 문제가 생기는데, 이를 해결하기 위한 것이 '원형 큐'와 '링크드 큐'이다
- 원형 큐의 경우, rear나 head가 큐의 끝에 도달하면 이를 큐의 맨 앞으로 보내 문제를 해결한다.
- 연결리스트로 구현한 큐를 의미한다.
- 삽입과 삭제가 제한되지 않으며 크기의 제한이 없다.
👀 아래의 세 가지 메소드를 활용해 큐를 구현한다.
enqueue/dequeue/peek
👉 스택에서와 마찬가지로, 배열과 연결 리스트를 이용해 구현할 수 있다.
1. 배열로 구현
class Queue:
def __init__(self):
self.queue = []
def isEmpty(self):
if not self.queue:
return True
else:
return False
def enqueue(self, data):
self.queue.append(data)
def dequeue(self):
if self.isEmpty():
return "Queue is Empty"
else:
dequeued = self.queue[0]
# 꺼낸 뒤 나머지 재정비
self.queue = self.queue[1:]
return dequeued
# front가 무엇인지만 보여준다.
def peek(self):
if self.isEmpty():
return "Queue is Empty"
else:
peeked = self.queue[0]
return peeked
2. 연결리스트로 구현
# Singly Linked List
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedListQueue:
def __init__(self):
self.front = None
self.rear = None
def isEmpty(self):
if self.front is None:
return True
else:
return False
def enqueue(self, data):
new_node = Node(data)
if self.isEmpty():
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
def dequeue(self):
if self.isEmpty():
return "Queue is Empty"
else:
dequeued = self.front
self.front = self.front.next
# front가 None이 되면 큐가 비었다는 뜻이므로 rear도 None
if self.front is None:
self.rear = None
return dequeued
def peek(self):
if self.isEmpty():
return "Queue is Empty"
else:
return self.front.data