Notice
Recent Posts
Recent Comments
Link
nathan_H
[자료구조] Queue 의 특징 및 활용예제 본문
큐는 스택 자료구조와 달리 FIFO (First-In First-Out)- 선입 선출 특징으로
- 넣을 때에는 한 쪽 끝에서 밀어 넣어야 한다. -> enqueue 연산
- 꺼낼 때에는 반대 쪽에서 뽑아 꺼내야하는 제약 -> dequeue 연산
즉 enqueue로 삽입된 원소가 가장 나중에 dequeue로 빠져나온다는 것이다.
추상적 자료구조 구현
method
- size() - 현재 큐에 들어 있는 데이터 원소의 수 O(1)
- isEmpty() - 현재 큐가 비어 있는지 판단 O(1)
- enqueue(x) - 데이터 원소 큐에 추가 O(1)
- dequeue - 큐에 맨 앞에 저장된 데이터 원소 제기 or 반환 O(n)
- peek() - 큐의 맨앞에 저장된 데이터 원소 반환(제거 x) O(1)
- dequeue 시간 복잡도 - 20, 37, 58, 65, 72, 91
> 맨앞에 요소를 뺌으로 인덱스가 순차적으로 앞으도 당겨와서 시간 복잡도가 O(n) 리스트가 길면 길수록 오래 걸린다.
Array로 구현
-> Python list Built-in method
class ArrayQueue:
def __init__(self):
self.data = []
def is_Empty(self):
return if not self.data
def size(self):
return len(self.data)
def enqueue(self, item):
self.data.append(item)
def dequeue(self):
return self.data.pop(0)
def peek(self):
return self.data[0]
DoublyLinkedList로 구현
class LinkdeListQueue:
def __init__(self):
self.data = DoublyLinkedList()
def is_Empty(self):
return self.data.getLength == 0
def size(self):
return self.data.getLength()
def enqueue(self, item):
newNode = Node(item)
self.data.insertAt(self.data.nodeCount + 1, newNode)
def dequeue(self):
return self.data.popAt(1)
def peek(self):
return self.data.getAt(1).data
선행 배열 or 연결 리스트중 머가 더 유리할까?
- 시간적인 측면은 연결 리스트가 유리.
- 메모리 측면에서는 선형 배열이 유리함.
시간을 우선순위를 두고 채택하는 경우가 많음.
큐 활용
-
자료를 생성하는 작업과 그 자료를 이용하는 작업이 비동기적으로 일어나는 경우
-
자료를 생성하는 작업과 그 자료를 이용하는 작업이 양쪽 다 여러 곳에서 이용하는 경우.
consumer <- product <- producer
consumer <- product <- producer1, producer2
consumer1, consumer2 <- product <- producer -
자료를 처리하여 새로운 자료를 생성하고, 나중에 그 자료를 또 처리해야 하는 작업의 경우
-
환형 큐
- 정해진 개수의 저장 공간을 빙 돌려가며 이용.
- 큐 길이를 기억하고 있어야 한다. (정해진 개수)
- front, rear -
priority queue
→ 큐가 FIFO 방식을 따르지 않고 원소드르이 우선순위에 따라 큐에서 빠져나오는 방식.
활용 예 - 운영체제의 cpu 스케쥴러
방식 1. enqueue 할 때 우선순위 순서를 유지하도록
방식 2. dequeue 할 때 우선순위 높은 것을 선택 → 어느 것이 유리 할까?
- 1번이 유리함. (무작위로 들어 갔을 때 dequeue 할때 원소를 다 찾아야함으로 오래 걸림)
환형 큐 코드 구현
class CircularQueue:
def __init__(self, counts):
self.data = [None] * counts
self.front = -1
self.rear = -1
self.maxCount = counts
self.count = 0
def is_Empty(self):
return self.count == 0
def size(self):
return self.count
def isFull(self):
return self.maxCount == self.count
def enqueue(self, item):
if self.isFull():
raise IndexError('Queue full')
self.rear = (self.rear + 1) % (self.maxCount)
self.data[self.rear] = item
self.count += 1
def dequeue(self):
if self.is_Empty():
raise IndexError('Queue empty')
self.front = (self.front + 1) % (self.maxCount)
x = self.data[self.front]
self.count -= 1
return x
def peek(self):
if self.is_Empty():
raise IndexError('Queue empty')
return self.data[(self.front + 1) % (self.maxCount)]
우선순위 큐 코드 구현
# from DoublyLinkedList.DoublyLinkedList import Node, DoublyLinkedList
class PriorityQueue:
def __init__(self):
self.queue = DoublyLinkedList()
def size(self):
return self.queue.getLength()
def is_Empty(self):
return self.queue.nodeCount == 0
def enqueue(self, x):
newNode = Node(x)
curr = self.queue.head
while curr.next != self.queue.tail and x < curr.next.data:
curr = curr.next
'''
while x < curr.next.data and curr.next != self.queue.tail
-> 만약 curr.next.data 가 None인 경우 TypeError: '<' not supported between instances of 'int' and 'NoneType'
하지만 while curr.next.data != None and x < curr.next.data
이런 순서로 할 경우에는 curr.next.data == None인 경우 뒤에 조건을 무시해 오류를 피해 갈 수 있다.
'''
self.queue.insertAfter(curr, newNode)
def dequeue(self):
return self.queue.popAt(self.queue.getLength())
def peek(self):
return self.queue.getAt(self.queue.getLength()).data
'Computer Science > DataStructure' 카테고리의 다른 글
[Stack] python으로 구현한 자료구조 stack (1) | 2019.07.06 |
---|---|
양방향 연결리스트(Double LinkedList) (0) | 2019.07.04 |
연결리스트의 특징과 파이썬 코드 구현 (0) | 2019.07.02 |
Comments