강의자료5
TRANSCRIPT
1
3 장
ADTs Stack and Queue
(Queue)
2
What is a Queue?
Logical (or ADT) level: A queue is an ordered group of homogeneous items (elements), in which new elements are added at one end (the rear), and elements are removed from the other end (the front).
순서가 있는 동형의 원소들의 모임 ; 원소 삽입은 한쪽 끝에서 일어나고 삭제는 다른쪽 끝에서 일어남
A queue is a FIFO “first in, first out” structure.
Queue ADT Operations
MakeEmpty -- Sets queue to an empty state.
IsEmpty -- Determines whether the queue is currently empty.
IsFull -- Determines whether the queue is currently full.
Enqueue (ItemType newItem) -- Adds newItem to the rear of the queue.
Dequeue (ItemType& item) -- Removes the item at the front of
the queue and returns it in item.3
ADT Queue Operations
Transformers MakeEmpty Enqueue Dequeue
Observers IsEmpty IsFull
change state
observe state
4
5
DYNAMIC ARRAY IMPLEMENTATION(circular queue)
QueType
~QueType
Enqueue
Dequeue . . .
class QueType
Private Data:
front 1
rear 4
maxQue 5
items‘C’ ‘X’ ‘J’
items [0] [1] [2] [3] [4]
RE
SE
RV
ED
6
큐 구현 - (1) 큐의 구현: 1차원 배열 items[] 이용(1) 큐의 첫번째 원소(front) 원소를 items[0]로 표현한 큐
A B C … B C D …B C …[0] [1] [2] [0] [1] [0] [1] [2]
rear rear rear
원소를 하나 삭제한 뒤의 상태 원소를 하나 삽입한 뒤의 상태
- 삭제 : queue[0] 에 있는 앞 원소를 제거
삭제할 때마다 나머지 원소들을 왼쪽으로 이동해야 함
큐가 n 개의 원소를 가질 때 , 삭제 시 Θ(n) 시간이 걸림
- 삽입 : 배열 크기 조절 시간을 제외하면 Θ(1) 시간이 걸림
7
큐 구현 - (2) 큐의 구현
(2) 큐의 첫번째 원소를 items[front] 로 표현한 큐 - 변수 front 를 사용하여 큐의 첫번째 위치를 항상 유지 - 원소의 삭제를 Θ(1) 시간에 수행하기 위한 방법
- 큐의 원소 : items[front], …, items[rear]
A B C … B C D …B C …
rear rear rear
첫번째 원소를 삭제한 뒤의 상태 원소를 하나 삽입한 뒤의 상태
front frontfront
8
큐 구현 - (2) 큐의 구현 (2) 큐의 첫번째 원소를 items[front] 로 표현한 큐 ( 계속 )
- 배열 queue 의 크기가 capacity 일 경우 , rear 가 capacity-1 과 같고 , front > 0 일 때 문제 발생 - 배열의 크기를 확장하지 않고 어떻게 원소를 삽입할까 ?
큐의 모든 원소를 왼쪽 끝으로 이동시켜 오른 쪽 끝에 공간을 만드는 방법
– 배열 이동에 많은 시간 소요 : 큐의 원소 수에 비례
원형 큐를 사용하는 방법 – 큐가 배열의 끝에서 되돌아오게 하여 최악의 경우 삽입 , 삭제 시간을
O(1) 으로 한다 .
… A B C D E A B C D E ...
rear rearfrontfront
(a) 이동 전 (b) 이동 후
9
큐 구현 - (3) 원형 큐 (Circular queue)
변수 front 는 큐에서 첫 원소의 위치를 가리킴 변수 rear 는 큐에서 마지막 원소의 위치 다음을 (
시계방향으로 ) 가리킴
A
B
C
A
B
C D
B
CD
rear rear rear
front front front
(a) 현재상태 (b) 삽입 (c) 삭제
10
Circular Queueitems
items[0]
items[1]
items[maxQue-1]
items[0]
items[1]
items[2]
items[maxQue-1]
논리적으로 배열의 시작과 끝이 이어져 있는 것으로 간주
11
경계조건 (boundary conditions)
items[maxQue-1]
front rear
a1
front rear Enqueue(a1)
Enqueue(a2)
a1 a2
front rear
Enqueue(a3)
a1 a2 a3
front rear
Dnqueue(x)
a2 a3
front rear
Queue is empty 인 상태 : rear == front
12
경계조건 (boundary conditions)
a2 a3
front rear
rear front Enqueue(…) … Dequeue(…) …
rear front Enqueue(…) ⇒ Queue is full
Queue 가 empty 일 경우와 full 일 경우 모두 front = rear 가 되어 구분이 가능하지 않다 .
따라서 , Queue 가 full 인 상태 : (rear +1) % maxQue == front
//--------------------------------------------------------// CLASS TEMPLATE DEFINITION FOR CIRCULAR QUEUE #include "ItemType.h" // for ItemType template<class ItemType>class QueType {public:
QueType( ); QueType( int max ); // PARAMETERIZED CONSTRUCTOR~QueType( ) ; // DESTRUCTOR
. . .bool IsFull( ) const;void Enqueue( ItemType item );void Dequeue( ItemType& item );
private:int front;int rear;int maxQue; ItemType* items; // DYNAMIC ARRAY IMPLEMENTATION
};13
//--------------------------------------------------------// CLASS TEMPLATE DEFINITION FOR CIRCULAR QUEUE cont’d//--------------------------------------------------------
template<class ItemType>QueType<ItemType>::QueType( int max ) // PARAMETERIZED{
maxQue = max + 1; front = 0;
rear = 0;items = new ItemType[maxQue]; // dynamically allocates
}template<class ItemType>QueType<ItemType>::QueType() // default class constructor
maxQue = 501; front = 0; rear = 0;
items = new ItemType[maxQue]; // dynamically allocates}template<class ItemType>bool QueType<ItemType>::IsEmpty( ){
return ( rear == front )}
14
//--------------------------------------------------------
// CLASS TEMPLATE DEFINITION FOR CIRCULAR QUEUE cont’d
//--------------------------------------------------------
template<class ItemType>
QueType<ItemType>::~QueType ( ) // 소멸자{
delete [ ] items; // deallocates array
}.
.
.
template<class ItemType>
bool QueType<ItemType>::IsFull( )
{
return ( (rear + 1) % maxQue == front ) // WRAP AROUND
}15
//--------------------------------------------------------// CLASS TEMPLATE DEFINITION FOR CIRCULAR QUEUE cont’d//--------------------------------------------------------template<class ItemType>void QueType<ItemType>::Enqueue(ItemType newitem ){
if( IsFull() ) {
cout << “Queue is full \n”; // 예외처리 return; } items[rear] = newitem; rear = (rear + 1) % maxQue; // WRAP AROUND}template<class ItemType>void QueType<ItemType>::Dequeue(ItemType &item ){ if( IsEmpty() ) {
cout << “Queue is empty \n”; // 예외처리 return; } item = items[front]; front = (front + 1) % maxQue; // WRAP AROUND}
16
17
SAYS ALL PUBLIC MEMBERS OF QueType CAN BE INVOKED FOR OBJECTS OF TYPE CountedQuType
// DERIVED CLASS CountedQueType FROM BASE CLASS QueType
template<class ItemType>class CountedQueType : public QueType<ItemType> {public:
CountedQueType( ); void Enqueue( ItemType newItem );void Dequeue( ItemType& item );int LengthIs( ) const;// Returns number of items on the counted queue.
private:int length;
};
18
class CountedQueType<char>
1919
// Member function definitions for class CountedQue
template<class ItemType> CountedQueType<ItemType>::CountedQueType( ) : QueType<ItemType>( ){
length = 0 ;}
template<class ItemType>int CountedQueType<ItemType>::LengthIs( ) const{
return length ;}
20
template<class ItemType>void CountedQueType<ItemType>::Enqueue( ItemType newItem )
// Adds newItem to the rear of the queue.// Increments length.
{length++;
QueType<ItemType>::Enqueue( newItem );}
template<class ItemType>void CountedQueType<ItemType>::Dequeue(ItemType& item )
// Removes item from the rear of the queue.// Decrements length.
{length--;
QueType<ItemType>::Dequeue( item );}