void QueueInit(Queue * pq);int QIsEmpty(Queue * pq);void Enqueue(Queue * pq, Data data);Data Dequeue(Queue * pq);Data QPeek(Queue * pq);


배열의 길이가 N이라면 데이터가 N-1개 채워졌을 때, 이를 꽉찬 것으로 간주한다.
F = RF = (R + 1) % (배열길이)#ifndef __C_QUEUE_H__
#define __C_QUEUE_H__
#define TRUE 1
#define FALSE 0
#define QUE_LEN 100
typedef int Data;
typedef struct _cQueue
{
int front; // F
int rear; // R
Data queArr[QUE_LEN];
} CQueue;
typedef CQueue Queue;
void QueueInit(Queue * pq);
int QIsEmpty(Queue * pq);
void Enqueue(Queue * pq, Data data);
Data Dequeue(Queue * pq);
Data QPeek(Queue * pq);
#endiffront, rearvoid QueueInit(Queue * pq) // 텅 빈 경우 front와 rear은 동일위치 가리킴
{
pq->front = 0; // front/rear 모두 0으로 초기화
pq->rear = 0;
}int QIsEmpty(Queue * pq)
{
if(pq->front == pq->rear) // 큐가 텅 비었다면
return TRUE;
else
return FALSE;
}int NextPosIdx(int pos)
{
return (pos+1) % QUE_LEN;
}enqueue, dequeue, peekvoid Enqueue(Queue * pq, Data data)
{
if(NextPosIdx(pq->rear) == pq->front) // 큐가 꽉 찼다면
{
printf("Queue Memory Error!");
exit(-1);
}
pq->rear = NextPosIdx(pq->rear); // rear를 한 칸 이동
pq->queArr[pq->rear] = data; // rear가 가리키는 곳에 데이터 저장
}Data Dequeue(Queue * pq)
{
if(QIsEmpty(pq))
{
printf("Queue Memory Error!");
exit(-1);
}
pq->front = NextPosIdx(pq->front); // front를 한 칸 이동
return pq->queArr[pq->front]; // front가 가리키는 데이터 반환
}Data QPeek(Queue * pq)
{
if(QIsEmpty(pq))
{
printf("Queue Memory Error!");
exit(-1);
}
return pq->queArr[NextPosIdx(pq->front)];
}#include <stdio.h>
#include "CircularQueue.h"
int main(void)
{
/*** Queue의 생성 및 초기화 ***/
Queue q;
QueueInit(&q);
/*** 데이터 넣기 ***/
Enqueue(&q, 1); Enqueue(&q, 2);
Enqueue(&q, 3); Enqueue(&q, 4);
Enqueue(&q, 5);
/*** 데이터 꺼내기 ***/
while(!QIsEmpty(&q))
printf("%d ", Dequeue(&q));
return 0;
}
1 2 3 4 5큐는 enqueue와 dequeue가 이뤄지는 위치가 다르다.
#ifndef __LB_QUEUE_H__
#define __LB_QUEUE_H__
#define TRUE 1
#define FALSE 0
typedef int Data;
typedef struct _node
{
Data data;
struct _node * next;
} Node;
typedef struct _lQueue
{
Node * front; // F
Node * rear; // R
} LQueue;
typedef LQueue Queue;
void QueueInit(Queue * pq);
int QIsEmpty(Queue * pq);
void Enqueue(Queue * pq, Data data);
Data Dequeue(Queue * pq);
Data QPeek(Queue * pq);
#endif

void QueueInit(Queue * pq)
{
pq->front = NULL;
pq->rear = NULL;
}int QIsEmpty(Queue * pq)
{
if(pq->front == NULL) // F에 NULL이 저장되면 큐가 빈 것이다.
return TRUE;
else
return FALSE;
}enqueue, dequeue, peek
Enqueue
void Enqueue(Queue * pq, Data data)
{
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->next = NULL;
newNode->data = data;
if(QIsEmpty(pq)) // 첫 번째 노드의 추가라면
{
pq->front = newNode; // front/rear 모두 새 노드를 가리킨다.
pq->rear = newNode;
}
else // 두 번째 이후의 노드 추가라면
{
pq->rear->next = newNode; // 마지막 노드가 새 노드를 가리키게 한다.
pq->rear = newNode; // rear가 새 노드를 가리키게 한다.
}
}
dequeue
Data Dequeue(Queue * pq)
{
Node * delNode;
Data retData;
if(QIsEmpty(pq))
{
printf("Queue Memory Error!");
exit(-1);
}
delNode = pq->front; // 삭제할 노드의 주소 값 저장
retData = delNode->data; // 삭제할 노드가 지닌 값 저장
pq->front = pq->front->next; // 삭제할 노드의 다음 노드를 front가 가리킴
free(delNode);
return retData;
}
peek
Data QPeek(Queue * pq)
{
if(QIsEmpty(pq))
{
printf("Queue Memory Error!");
exit(-1);
}
return pq->front->data;
}
void DequeInit(Deque * pdeq);int DQIsEmpty(Deque * pdeq);void DQAddFirst(Deque * pdeq, Data data);void DQAddLast(Deque * pdeq, Data data);Data DQRemoveFirst(Deque * pdeq);Data DQRemoveLast(Deque * pdeq);Data DQGetFirst(Deque * pdeq);Data DQGetLast(Deque * pdeq);
‘양방향 연결 리스트’를 기반으로 덱을 구현한다.
- Data DQRemoveLast(Deque * pdeq); : tail에 위치한 노드를 삭제하는 데 용이하다.
- 기존의 양방향 연결 리스트와 달리 포인터 변수 tail을 둬서 리스트의 꼬리를 가리킨다.
#ifndef __DEQUE_H__
#define __DEQUE_H__
#define TRUE 1
#define FALSE 0
typedef int Data;
typedef struct _node
{
Data data;
struct _node * next;
struct _node * prev;
} Node;
typedef struct _dlDeque
{
Node * head;
Node * tail;
} DLDeque;
typedef DLDeque Deque;
void DequeInit(Deque * pdeq);
int DQIsEmpty(Deque * pdeq);
void DQAddFirst(Deque * pdeq, Data data);
void DQAddLast(Deque * pdeq, Data data);
Data DQRemoveFirst(Deque * pdeq);
Data DQRemoveLast(Deque * pdeq);
Data DQGetFirst(Deque * pdeq);
Data DQGetLast(Deque * pdeq);
#endif
void DequeInit(Deque * pdeq) // head,tail 모두 NULL로 초기화
{
pdeq->head = NULL;
pdeq->tail = NULL;
}int DQIsEmpty(Deque * pdeq)
{
if(pdeq->head == NULL) // head가 NULL이면 비어있는 덱이다.
return TRUE;
else
return FALSE;
}void DQAddFirst(Deque * pdeq, Data data)
{
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = pdeq->head; // 덱의 왼쪽에 원소 삽입
if(DQIsEmpty(pdeq)) // 덱이 빈 경우에 대한 예외 처리(덱의 삭제를 위한 처리)
pdeq->tail = newNode;
else
pdeq->head->prev = newNode;
newNode->prev = NULL; // 덱의 첫 번째 원소임을 의미
pdeq->head = newNode; // 덱의 첫 번째 원소로 표시
}void DQAddLast(Deque * pdeq, Data data)
{
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->prev = pdeq->tail; // 덱의 오른쪽에 원소 삽입
if(DQIsEmpty(pdeq))
pdeq->head = newNode;
else
pdeq->tail->next = newNode;
newNode->next = NULL; // 덱의 마지막 원소임을 의미
pdeq->tail = newNode; // 덱의 마지막 원소로 표시
}Data DQRemoveFirst(Deque * pdeq)
{
Node * rnode = pdeq->head; // 삭제할 노드
Data rdata = pdeq->head->data; // 삭제할 노드가 지닌 값 저장
if(DQIsEmpty(pdeq))
{
printf("Deque Memory Error!");
exit(-1);
}
pdeq->head = pdeq->head->next; // head 위치를 오른쪽으로 옮김
free(rnode);
if(pdeq->head == NULL) // 덱이 비어 있음(초기화)
pdeq->tail = NULL;
else
pdeq->head->prev = NULL; // 첫 번째 원소임을 의미
return rdata;
}Data DQRemoveLast(Deque * pdeq)
{
Node * rnode = pdeq->tail; // 삭제할 노드
Data rdata = pdeq->tail->data; // 삭제할 노드가 지닌 값 저장
if(DQIsEmpty(pdeq))
{
printf("Deque Memory Error!");
exit(-1);
}
pdeq->tail = pdeq->tail->prev; // tail 위치를 왼쪽으로 옮김
free(rnode);
if(pdeq->tail == NULL) // 덱이 비어 있음(초기화)
pdeq->head = NULL;
else
pdeq->tail->next = NULL; // 마지막 원소임을 의미
return rdata;
}Data DQGetFirst(Deque * pdeq)
{
if(DQIsEmpty(pdeq))
{
printf("Deque Memory Error!");
exit(-1);
}
return pdeq->head->data;
}Data DQGetLast(Deque * pdeq)
{
if(DQIsEmpty(pdeq))
{
printf("Deque Memory Error!");
exit(-1);
}
return pdeq->tail->data;
}참고: 윤성우의 열혈 자료구조