-> 블로그 이전

[Data Structure] 덱 (Deque)

2021. 12. 7. 16:12Major`/자료구조

덱 (Deque - Double Ended Queue)

- 큐(Queue) : 전단(front)에서 삭제, 후단(rear)에서 삽입

- 덱(Deque) : 큐의 전단(front), 후단(rear)에서 모두 삽입/삭제 가능

 

 

※ Example

- delete_rear / add_front

- MAX_DEQUE_SIZE = 5

front rear 과정
0 0 Deque 초기화
0 1 add_rear
0 2 add_rear (1)
4 2 add_front (2)
3 2 add_front → 포화
4 2 delete_front
0 2 delete_front (3)
0 1 delete_rear (4)
0 0 delete_rear → 공백

(1) → (2)

front에서 add를 하려면 원래 front 인덱스에 item을 add 시키고, front를 한 칸 뒤로 옮기기(front - 1)

  • → front - 1이 음수일 경우, (front-1)에다가 MAX_DEQUE_SIZE를 더하기 → (front-1+MAX_DEQUE_SIZE)
  • 더한 값(front-1+MAX_DEQUE_SIZE)을 MAX_DEQUE_SIZE로 나눈 나머지 = front 인덱스 값

add_front를 거친 front의 다음 인덱스 = (front-1+MAX_DEQUE_SIZE)%MAX_DEQUE_SIZE 

(3) → (4)

add_front와 마찬가지로, delete_rear은 현재 rear 인덱스에 있는 item을 다른 변수에 보관

  • → 보관하고, rear를 한 칸 뒤로 옮기기(rear-1)

delete_rear를 거친 rear의 다음 인덱스 = (rear-1+MAX_DEQUE_SIZE)%MAX_DEQUE_SIZE 

 

 

1.add_rear (int rear)

- 큐의 enqueue와 동일한 알고리즘

void add_rear(deque* d, element item) {
	// 큐의 enqueue와 동일
	if (is_full(d)) {
		fprintf(stderr, "Error : Deque is full\n");
		return;
	}
	else {
		d->rear = (d->rear + 1) % MAX_DEQUE_SIZE;
		d->deque[d->rear] = item;
	}
}

 

 

2. add_front (int front)

- 현재 front 인덱스에 item을 삽입

  • → 삽입 후, front를 1칸 뒤로 옮기기 (front-1)
void add_front(deque* d, element item) {
	// front에 item을 넣고 front를 1칸 뒤로 설정
	if (is_full(d)) {
		fprintf(stderr, "Error : Deque is full\n");
		return;
	}
	else {
		d->deque[d->front] = item;
		d->front = (d->front - 1 + MAX_DEQUE_SIZE) % MAX_DEQUE_SIZE;
		/* 
		d->front - 1 의 결과가 음수일 경우, MAX_DEQUE_SIZE를 더하고,
		더한 최종 결과에 MAX_DEQUE_SIZE로 나눠준다
		*/
	}
}

 

 

3. delete_rear (int rear)

element delete_rear(deque* d) {
	// d->rear에 있는 item을 따로 보관하고, d->rear을 1칸 뒤로 옮긴다
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else {
		element item = d->rear;
		d->rear = (d->rear - 1 + MAX_DEQUE_SIZE) % MAX_DEQUE_SIZE;
		return d->deque[item];
	}
}

 

 

4. delete_front (int front)

- 큐의 dequeue와 동일한 알고리즘

element delete_front(deque* d) {
	// 큐의 dequeue와 동일
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else {
		d->front = (d->front + 1) % MAX_DEQUE_SIZE;
		return d->deque[d->front];
	}
}

 

 

5. Full Code (Deque With Array)

#include <stdio.h>
#include <stdlib.h>
#define MAX_DEQUE_SIZE 5
// 덱 (원형으로 구현)

typedef int element;

typedef struct {
	int front, rear;
	element deque[MAX_DEQUE_SIZE];
}deque;

int size(deque *d){
	return MAX_DEQUE_SIZE;
}

void init_deque(deque* d) {
	d->front = d->rear = 0;
}

int is_full(deque* d) {
	return d->front == (d->rear + 1) % MAX_DEQUE_SIZE;
}

int is_empty(deque* d) {
	return d->front == d->rear;
}

void add_rear(deque* d, element item) {
	// 큐의 enqueue와 동일
	if (is_full(d)) {
		fprintf(stderr, "Error : Deque is full\n");
		return;
	}
	else {
		d->rear = (d->rear + 1) % MAX_DEQUE_SIZE;
		d->deque[d->rear] = item;
	}
}

void add_front(deque* d, element item) {
	// front에 item을 넣고 front를 1칸 뒤로 설정
	if (is_full(d)) {
		fprintf(stderr, "Error : Deque is full\n");
		return;
	}
	else {
		d->deque[d->front] = item;
		d->front = (d->front - 1 + MAX_DEQUE_SIZE) % MAX_DEQUE_SIZE;
		/* 
		d->front - 1 의 결과가 음수일 경우, MAX_DEQUE_SIZE를 더하고,
		더한 최종 결과에 MAX_DEQUE_SIZE로 나눠준다
		*/
	}
}

element delete_rear(deque* d) {
	// d->rear에 있는 item을 따로 보관하고, d->rear을 1칸 뒤로 옮긴다
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else {
		element item = d->rear;
		d->rear = (d->rear - 1 + MAX_DEQUE_SIZE) % MAX_DEQUE_SIZE;
		return d->deque[item];
	}
}

element delete_front(deque* d) {
	// 큐의 dequeue와 동일
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else {
		d->front = (d->front + 1) % MAX_DEQUE_SIZE;
		return d->deque[d->front];
	}
}

element peek_rear(deque* d) {
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else 
		return d->deque[d->rear];
}

element peek_front(deque* d) {
	if (is_empty(d)) {
		fprintf(stderr, "Error : Deque is empty\n");
		return;
	}
	else 
		return d->deque[(d->front + 1) % MAX_DEQUE_SIZE];
}

void deque_print(deque* d) {
	printf("DEQUE(front=%d rear=%d) = ", d->front, d->rear);
	if (!is_empty(d)) {
		element item = d->front;
		do {
			item = (item + 1) % MAX_DEQUE_SIZE;
			printf("%d |	", d->deque[item]);
			if (item == d->rear)
				break;
		} while (item != d->front);
	}
	printf("\n");
}

int main(void) {
	deque d;
	init_deque(&d);

	printf("Deque Size : %d\n\n", size(&d));

	printf(">>> add_rear 10\n"); add_rear(&d, 10); deque_print(&d);
	printf("\n>>> add_rear 20\n"); add_rear(&d, 20); deque_print(&d);
	printf("\n>>> add_front 30\n"); add_front(&d, 30); deque_print(&d);
	printf("\n>>> add_front 40\n"); add_front(&d, 40); deque_print(&d);
	printf("\n>>> add_front 50\n"); add_front(&d, 50); deque_print(&d);

	printf("\n>>> peek_rear\n"); printf("%d\n", peek_rear(&d));
	printf("\n>>> peek_front\n"); printf("%d\n", peek_front(&d));

	printf("\n>>> delete_rear\n"); delete_rear(&d); deque_print(&d);
	printf("\n>>> delete_rear\n"); delete_rear(&d); deque_print(&d);
	printf("\n>>> delete_front\n"); delete_front(&d); deque_print(&d);
	printf("\n>>> delete_front\n"); delete_front(&d); deque_print(&d);
	printf("\n>>> delete_front\n"); delete_front(&d); deque_print(&d);
}