자구알 공부 겸 백준 재시작.
이번 문제는 Queue 자료구조를 구현하는 문제이다. 리스트 노드를 이용한 방식으로 Queue를 구현한다.
문제
정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 여섯 가지이다.
push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다. size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 2,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
QlistNode
typedef struct QlistNode
{
int data;
struct QlistNode *rlink;
} QlistNode;
element data와 다음 노드를 가리키는 QlistNode 포인터 rlink로 구성한다.
QueueType
typedef struct
{
QlistNode *front;
QlistNode *rear;
int size;
} QueueType;
Queue 자료구조를 정의한다. front와 rear 포인터, 그리고 Queue의 크기를 나타내는 size 변수로 구성한다.
다음으로 함수들을 정의한다.
createNode
QlistNode *createNode(int item)
{
QlistNode *newNode = (QlistNode *)malloc(sizeof(QlistNode));
newNode->data = item;
newNode->rlink = NULL;
return newNode;
}
Queue 노드를 생성하는 함수. QlistNode 타입 포인터 newNode를 동적 할당한다. data에 item을 저장하고 rlink를 NULL로 설정한 후 반환한다.
isEmpty
bool isEmpty(QueueType *q)
{
return !(q->size);
}
Queue가 비었는지 확인하는 함수. size가 0이면 빈 상태로 1을 반환하고 비어있지 않다면 0을 반환한다.
enqueue
void enqueue(QueueType *q, int item)
{
QlistNode *newNode = createNode(item);
if (isEmpty(q))
q->front = newNode;
else
q->rear->rlink = newNode;
q->size++;
q->rear = newNode;
}
삽입함수. createNode 함수를 호출해 새 노드를 생성한다. Queue가 비어있다면 newNode가 front가 된다. 비어있지 않다면 rear의 rlink를 newNode로 설정한다. 삽입 후에는 size를 1 증가시키고 rear가 newNode가 된다.
dequeue
int dequeue(QueueType *q)
{
if (isEmpty(q))
return -1;
else
{
int dequeued = q->front->data;
QlistNode *temp = q->front;
q->front = q->front->rlink;
free(temp);
q->size--;
if (q->front == NULL)
q->rear = NULL;
return dequeued;
}
}
삭제 함수. Queue가 비어있다면 -1을 반환한다. 비어있지 않다면 삭제 연산을 수행한다. 우선 현재 front의 data를 dequeued라는 변수에 저장한다. 임시 노드 temp에 front를 저장한다. front에 front의 rlink를 저장하고 temp를 메모리 해제한다. 삭제 후에는 size를 1 감소시키고, 만약 front가 NULL이 되었다면(Queue가 비게 되었다면) rear도 NULL로 설정해준다. dequeued를 반환한다.
front/rear
int front(QueueType *q)
{
if (isEmpty(q))
return -1;
else
return q->front->data;
}
int rear(QueueType *q)
{
if (isEmpty(q))
return -1;
else
return q->rear->data;
}
Queue가 비었다면 -1을 반환하고 그렇지 않다면 각각 front, rear의 data를 반환한다.
main
int main()
{
QueueType *Queue = (QueueType *)malloc(sizeof(QueueType));
Queue->front = NULL;
Queue->rear = NULL;
Queue->size = 0;
int N;
char cmd[6];
const char *function[] = {"push", "pop", "size", "empty", "front", "back"};
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
scanf("%s", cmd);
if (!strcmp(function[0], cmd))
{
int item;
scanf("%d", &item);
enqueue(Queue, item);
}
else if (!strcmp(function[1], cmd))
printf("%d\n", dequeue(Queue));
else if (!strcmp(function[2], cmd))
printf("%d\n", Queue->size);
else if (!strcmp(function[3], cmd))
printf("%d\n", isEmpty(Queue));
else if (!strcmp(function[4], cmd))
printf("%d\n", front(Queue));
else if (!strcmp(function[5], cmd))
printf("%d\n", rear(Queue));
}
free(Queue);
return 0;
}
QueueType 포인터 Queue를 메모리 동적 할당으로 생성하고 각 멤버를 초기화해준다. N은 명령의 수, cmd는 명령을 담을 문자열, function은 명령들을 저장해둔 문자열 배열이다. N을 입력받고, cmd에 명령을 입력받은 후 function 배열의 명령들과 strcmp함수를 이용해 비교해서 각 명령에 맞게 수행한다.
늘 그렇듯이 ;빼먹고 오타내고 cmd 길이를 5로 설정하는 등 이상한 짓하다가 성공
출처: 백준
'Baekjoon' 카테고리의 다른 글
[Baekjoon] 11650: 좌표 정렬하기 - (C2, S5) std::sort (0) | 2025.01.01 |
---|---|
[Baekjoon] 1436: 영화감독 숌 - (C2, S5) Brute Force (0) | 2024.12.30 |
[Baekjoon] 1874: 스택 수열 - (C2, S2) (0) | 2024.12.17 |
[Baekjoon] 2164: 카드2 (0) | 2024.11.18 |
[Baekjoon] 1914: 하노이 탑 (4) | 2024.08.21 |