this refers to 윤성우의 열혈자료구조.
now I introduce data structure queue.
you make the queue based on array and linkedList.
functionality of queue consists of enqueue and dequeue.
the enqueue puts a data in queue.
the dequeue remove a data from queue
1-1 ADT of queue
1-1-1. void QueueInit(Queue * pq)
- intialized the queue.(큐를 초기화 한다.)
- you call this function after creating new queue right. (큐 생성후 바로 호출되어야 한다. )
1-1-2. int QIsEmpty(Queue * pq)
- if the queue is empty, this function returns TRUE(1).
- if not, this function returns FALSE(0).
- (큐가 비어 있으면 TRUE(1), 아니면 FALSE(0)을 반환한다.)
1-1-3. void Enqueue (Queue * pq, Data data)
- this stores data int queue.
- 큐에 데이터를 저장한다. 매개변수 data로 전달된 값을 저장한다.
1-1-4. Data Dequeue(Queue * pq)
- this removes the data which is stored the most early.
- this returns data that is removed.
- it guarantees that the queue have one data. when this function is called.
- 저장 순서가 앞선 데이터 삭제, 삭제된 데이터 반환, 이함수 호출시 반드시 하나의 데이터가 저장되어 있어야 한다.
1-1-5. Data QPeek(Queue * pq)
- this just identifies the most early data and don't remove the data.
- it guarantees that the queue have one data. when this function is called.
- 저장 순서가 가장 빠른 데이터 참조만 하고, 삭제는 하지 않는다.
- 이 함수 호출시 데이터가 최소한 하나이상은 존재해야한다.
1-2. implement of queue
1-2-1. concept of queue
- the following picture show you enqueue & dequeue method.
1-2-2. problem of queue based on array.
- after moving R to the right. queue stores a data. but when queue stores D,
- the queue don't go to right, so R moves to the first position(index 0).
- however, as you utilize the circular queue, the problem is easy.
- 배열이다 보니 배열을 크기가 한정되어 있다.
- 그래서 배열 끝가지 데이터를 저장하면 인덱스 0부터 저장을 하던지 배열의 크기를 늘려야 한다.
- 만약 인덱스 0에서 다시 시작을 한다면 이것을 원형 큐라고 한다.
1-2-3. introduction of circular queue
- you think of linear Array as circle.
- 선형 구조인 배열을 원으로 생각을 해라. 그것이 원형 큐의 시작이다.
1-2-4. circular queue has a problem
- you make a distinction between the empty queue and the pull queue with R & F.
- but circular queue don't make distinction the both, as follows
- front & rear을 가지고 큐가 비어있는지 아닌지 구분하기 힘들다.
- but we have a solution, as follows.
- after the first storage is empty, and you put data in the circular queue.
- So we can make a distinction between the empty queue and the pull queue with R & F.
- if the queue is empty, F & R is located in the same position.
- if the queue is full, F & R is located in the different position.
- 큐의 꽉찬 상태와 아닌 상태를 구분을 위해서 배열의 한칸을 비우고 데이터를 저장한다.
- 이로써 Rear & front가 같다면 큐는 비어있는 상태, 같지 않으면 데이터가 안에 있다는 상태를 나타낸다.
1-2-5. headfile of Source code
1-2-6. Function helping the circular queue
- this function helps the circular queue to decide next index to store a data.
- 아래의 함수가 배열을 원형으로 인식할 수 있게 도와 준다.
// the following is good method. so you apply to other.
// you need to this function to make the circular queue
int NextPosIdx(int pos)
{
if (pos == QUE_LEN -1)
return 0;
else
return pos +1;
}
void QueueInit(Queue * pq)
{
pq -> front =0;
pq -> rear = 0;
}
int QIsempty(Queue * pq)
{
if(pq -> front == pq -> rear)
return TRUE;
else
return FALSE;
}
void Enqueue(Queue * pq, Data data)
{
if(NextPosIdx(pd -> rear) == pq -> front)
{
printf("Queue is full\n");
exit (-1);
}
pq -> rear = NextPosIdx(pq -> rear);
pq -> queArr[pq -> rear] = data;
}
// 큐의 첫번째 인덱스는 비어 있다.
// 꼭 기억
Data Dequeue(Queue * pq)
{
if(QIsEmpty(pq))
{
printf("Queue is empty\n");
exit(-1);
}
pq -> front = NextPosIdx(pq -> front);
return pq -> queArr[pq -> front];
}
// example of main function
int main(void)
{
// initialization queue
Queue q;
QueueInit(&q);
// put data in the queue
Enqueue(&q, 1);
Enqueue(&q, 2);
Enqueue(&q, 3);
Enqueue(&q, 4);
Enqueue(&q, 5);
// remove data from queue
while (!QIsEmpty(&q))
{
printf("%d ", Dequeue(&q));
}
return 0;
}
// the result of main function
-> 1 2 3 4 5