mirror of
https://github.com/krahets/hello-algo.git
synced 2026-11-02 03:05:24 +08:00
* feat(ko): add the complete Korean online edition * Use UTF-8 for Python CI output on Windows * Remove print-book promotion from the Korean site * fix(ko): preserve emphasis before Korean particles
172 lines
5.0 KiB
C
172 lines
5.0 KiB
C
/**
|
|
* File: array_deque.c
|
|
* Created Time: 2023-03-13
|
|
* Author: Gonglja ([email protected])
|
|
*/
|
|
|
|
#include "../utils/common.h"
|
|
|
|
/* 원형 배열로 구현한 덱 */
|
|
typedef struct {
|
|
int *nums; // 큐의 원소를 저장하는 배열
|
|
int front; // 맨 앞 원소를 가리키는 맨 앞 포인터
|
|
int queSize; // 맨 뒤 포인터, 큐의 맨 뒤 + 1을 가리킨다
|
|
int queCapacity; // 큐 용량
|
|
} ArrayDeque;
|
|
|
|
/* 생성자 */
|
|
ArrayDeque *newArrayDeque(int capacity) {
|
|
ArrayDeque *deque = (ArrayDeque *)malloc(sizeof(ArrayDeque));
|
|
// 배열 초기화
|
|
deque->queCapacity = capacity;
|
|
deque->nums = (int *)malloc(sizeof(int) * deque->queCapacity);
|
|
deque->front = deque->queSize = 0;
|
|
return deque;
|
|
}
|
|
|
|
/* 소멸자 */
|
|
void delArrayDeque(ArrayDeque *deque) {
|
|
free(deque->nums);
|
|
free(deque);
|
|
}
|
|
|
|
/* 덱의 용량 반환 */
|
|
int capacity(ArrayDeque *deque) {
|
|
return deque->queCapacity;
|
|
}
|
|
|
|
/* 덱의 길이 반환 */
|
|
int size(ArrayDeque *deque) {
|
|
return deque->queSize;
|
|
}
|
|
|
|
/* 덱이 비어 있는지 판단 */
|
|
bool empty(ArrayDeque *deque) {
|
|
return deque->queSize == 0;
|
|
}
|
|
|
|
/* 원형 배열 인덱스 계산 */
|
|
int dequeIndex(ArrayDeque *deque, int i) {
|
|
// 나머지 연산을 통해 배열의 처음과 끝을 연결한다
|
|
// i가 배열의 끝을 넘어가면 처음으로 돌아온다
|
|
// i가 배열의 처음을 넘어가면 끝으로 돌아온다
|
|
return ((i + capacity(deque)) % capacity(deque));
|
|
}
|
|
|
|
/* 맨 앞에 삽입 */
|
|
void pushFirst(ArrayDeque *deque, int num) {
|
|
if (deque->queSize == capacity(deque)) {
|
|
printf("덱이 가득 찼다\r\n");
|
|
return;
|
|
}
|
|
// 맨 앞 포인터를 왼쪽으로 한 칸 이동한다
|
|
// 나머지 연산으로 front가 배열의 처음을 넘어가면 끝으로 돌아가게 한다
|
|
deque->front = dequeIndex(deque, deque->front - 1);
|
|
// num을 큐의 맨 앞에 추가한다
|
|
deque->nums[deque->front] = num;
|
|
deque->queSize++;
|
|
}
|
|
|
|
/* 맨 뒤에 삽입 */
|
|
void pushLast(ArrayDeque *deque, int num) {
|
|
if (deque->queSize == capacity(deque)) {
|
|
printf("덱이 가득 찼다\r\n");
|
|
return;
|
|
}
|
|
// 맨 뒤 인덱스 + 1을 가리키는 맨 뒤 포인터를 계산한다
|
|
int rear = dequeIndex(deque, deque->front + deque->queSize);
|
|
// num을 맨 뒤에 추가한다
|
|
deque->nums[rear] = num;
|
|
deque->queSize++;
|
|
}
|
|
|
|
/* 맨 앞 원소 접근 */
|
|
int peekFirst(ArrayDeque *deque) {
|
|
// 접근 예외: 덱이 비어 있다
|
|
assert(empty(deque) == 0);
|
|
return deque->nums[deque->front];
|
|
}
|
|
|
|
/* 맨 뒤 원소 접근 */
|
|
int peekLast(ArrayDeque *deque) {
|
|
// 접근 예외: 덱이 비어 있다
|
|
assert(empty(deque) == 0);
|
|
int last = dequeIndex(deque, deque->front + deque->queSize - 1);
|
|
return deque->nums[last];
|
|
}
|
|
|
|
/* 맨 앞에서 꺼내기 */
|
|
int popFirst(ArrayDeque *deque) {
|
|
int num = peekFirst(deque);
|
|
// 맨 앞 포인터를 뒤로 한 칸 이동한다
|
|
deque->front = dequeIndex(deque, deque->front + 1);
|
|
deque->queSize--;
|
|
return num;
|
|
}
|
|
|
|
/* 맨 뒤에서 꺼내기 */
|
|
int popLast(ArrayDeque *deque) {
|
|
int num = peekLast(deque);
|
|
deque->queSize--;
|
|
return num;
|
|
}
|
|
|
|
/* 출력에 사용할 배열 반환 */
|
|
int *toArray(ArrayDeque *deque, int *queSize) {
|
|
*queSize = deque->queSize;
|
|
int *res = (int *)calloc(deque->queSize, sizeof(int));
|
|
int j = deque->front;
|
|
for (int i = 0; i < deque->queSize; i++) {
|
|
res[i] = deque->nums[j % deque->queCapacity];
|
|
j++;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/* 실행 코드 */
|
|
int main() {
|
|
/* 큐 초기화 */
|
|
int capacity = 10;
|
|
int queSize;
|
|
ArrayDeque *deque = newArrayDeque(capacity);
|
|
pushLast(deque, 3);
|
|
pushLast(deque, 2);
|
|
pushLast(deque, 5);
|
|
printf("덱 deque = ");
|
|
printArray(toArray(deque, &queSize), queSize);
|
|
|
|
/* 원소 접근 */
|
|
int peekFirstNum = peekFirst(deque);
|
|
printf("맨 앞 원소 peekFirst = %d\r\n", peekFirstNum);
|
|
int peekLastNum = peekLast(deque);
|
|
printf("맨 뒤 원소 peekLast = %d\r\n", peekLastNum);
|
|
|
|
/* 큐에 원소 삽입 */
|
|
pushLast(deque, 4);
|
|
printf("원소 4를 맨 뒤에 삽입한 후 deque = ");
|
|
printArray(toArray(deque, &queSize), queSize);
|
|
pushFirst(deque, 1);
|
|
printf("원소 1을 맨 앞에 삽입한 후 deque = ");
|
|
printArray(toArray(deque, &queSize), queSize);
|
|
|
|
/* 큐에서 원소 꺼내기 */
|
|
int popLastNum = popLast(deque);
|
|
printf("맨 뒤에서 꺼낸 원소 = %d, 꺼낸 후 deque= ", popLastNum);
|
|
printArray(toArray(deque, &queSize), queSize);
|
|
int popFirstNum = popFirst(deque);
|
|
printf("맨 앞에서 꺼낸 원소 = %d, 꺼낸 후 deque= ", popFirstNum);
|
|
printArray(toArray(deque, &queSize), queSize);
|
|
|
|
/* 큐의 길이 반환 */
|
|
int dequeSize = size(deque);
|
|
printf("덱의 길이 size = %d\r\n", dequeSize);
|
|
|
|
/* 큐가 비어 있는지 판단 */
|
|
bool isEmpty = empty(deque);
|
|
printf("큐가 비어 있는가 = %s\r\n", isEmpty ? "true" : "false");
|
|
|
|
// 메모리 해제
|
|
delArrayDeque(deque);
|
|
|
|
return 0;
|
|
} |