본문 바로가기
Programming/자료구조

데크 Deque

by Bam_t 2021. 9. 18.
728x90

이번에 소개할 자료구조는 데크(덱)입니다. 어떤 문서에서는 데크, 다른 문서에서는 덱이라고 하길래 저는 제가 배웠던 '데크'라는 명칭으로 소개하려고합니다.


1. 데크

데크는 새로운 자료구조 같지만 큐의 변형 자료구조 중 하나입니다. 데크의 의미는 Double Ended Queue로써 끝이 2개인 큐를 의미합니다. 기존의 큐는 아래 그림처럼 한 끝에서만 삽입, 다른 한 끝에서만 삭제가 이루어졌습니다. 하지만 데크는 양 쪽 끝에서 삽입과 삭제가 모두 가능한 자료구조입니다. 한 가지 착각 하지 말아야 하는 점은 연결 리스트처럼 중간 삭제는 불가능하고 스택과 큐처럼 자료구조 양 끝에서만 삽입 삭제가 이루어 진다는 점입니다.

데크

구현 방식은 데크의 특징을 잘 생각해서 다음 두가지만 명심하고 구현하면됩니다.

  • front에서 삭제와 삽입
  • rear에서 삭제와 삽입

 

 

 

2. 데크의 구현

2-1. 노드 구성

데크는 양방향의 성격을 띄고있습니다. 그래서 이중 연결리스트와 유사한 듯한 느낌도 있는데요. 노드 구성이 이중 연결 리스트 처럼 데이터 필드 양옆에 링크 필드를 가지고 있습니다.

typedef struct DequeNode {
	element data;
	struct DequeNode* leftLink;
	struct DequeNode* rightLink;
}DequeNode;

 

 

2-2. 인큐

언급했듯이 front와 rear 양쪽에서 인큐/디큐가 이루어지므로, 두 개의 함수가 만들어져야합니다. 우선 front 인큐를 보겠습니다.

int insertFront(DequeType* DQ, element elem) {
	DequeNode* newNode = (DequeNode*)malloc(sizeof(DequeNode));

	newNode->data = elem;

	if (DQ->front == NULL) { //front가 비어있다면, 즉 첫 노드라면
		DQ->front = newNode;	
		DQ->rear = newNode;	//front와 rear가 인큐된 노드이며,

		newNode->rightLink = NULL;
		newNode->leftLink = NULL;	//가리키고 있는 다른 노드는 없다.
	}
	else {
    		//프론트로 삽입
        	//삽입 이전 프론트의 왼쪽 링크가 새노드를 가리키게한다.
		DQ->front->leftLink = newNode;

		newNode->rightLink = DQ->front;	//새 노드의 오른쪽 링크는 이전 front를 가리키게한다.
		newNode->leftLink = NULL;

		DQ->front = newNode; //마지막으로 front를 삽입한 노드로 설정
	}
}

그림으로 인큐과정을 그려보았습니다.

그러면 반대로 rear에서 인큐하는 과정을 보겠습니다.

void insertRear(DequeType* DQ, element elem) {
	DequeNode* newNode = (DequeNode*)malloc(sizeof(DequeNode));

	newNode->data = elem;

	if (DQ->rear == NULL) {
		DQ->front = newNode;
		DQ->rear = newNode;

		newNode->rightLink = NULL;
		newNode->leftLink = NULL;
	}
	else {
		DQ->rear->rightLink = newNode;

		newNode->rightLink = NULL;
		newNode->leftLink = DQ->rear;

		DQ->rear = newNode;
	}
}

 

2-3. 디큐

void deleteFront(DequeType* DQ) {	//front에서 디큐 실행
	DequeNode* oldNode = DQ->front;
	
	if (isEmpty(DQ)) {
		return 0;
	}
	else {
		if (DQ->front->rightLink == NULL) { //front노드가 유일한 노드일 때
			DQ->front = NULL;
			DQ->rear = NULL;
		}
		else {
        		//front를 front의 다음 노드로 설정
			DQ->front = DQ->front->rightLink;
            		//front 왼쪽 링크필드를 비움. 즉, 왼쪽 링크는 아무것도 안가리키게 된다.
			DQ->front->leftLink = NULL;
		}

		free(oldNode);

		return 0;
	}
}

else문 부분을 그림으로 표현했습니다. front를 이동시키고 연결을 끊음으로써 삭제가 됩니다.

element deleteRear(DequeType* DQ) {
	DequeNode* oldNode = DQ->rear;

	if (isEmpty(DQ)) {
		return 0;
	}
	else {
		if (DQ->rear->leftLink == NULL) {
			DQ->front = NULL;
			DQ->rear = NULL;
		}
		else {
			DQ->rear = DQ->rear->leftLink;
			DQ->rear->rightLink = NULL;
		}

		free(oldNode);

		return 0;
	}
}

 

2-4. 피크

피크도 마찬가지로 front의 요소를 보는 피크와 rear의 요소를 보는 피크로 나뉩니다.

element peekFront(DequeType* DQ) {
	element elem;

	if (isEmpty(DQ)) {
		return 0;
	}
	else {
		return elem = DQ->front->data;
	}
}

element peekRear(DequeType* DQ) {
	element elem;

	if (isEmpty(DQ)) {
		return 0;
	}
	else {
		return elem = DQ->rear->data;
	}
}

간단하게도, front피크라면 front의 데이터를, rear피크라면 rear의 데이터를 return 하면 됩니다.


https://github.com/Bam-j/DataStructure/blob/main/DataStructure/Deque.c

 

GitHub - Bam-j/DataStructure: 블로그와 함께 가는 자료구조

블로그와 함께 가는 자료구조. Contribute to Bam-j/DataStructure development by creating an account on GitHub.

github.com

 

 

728x90

'Programming > 자료구조' 카테고리의 다른 글

이진 트리 Binary Tree  (0) 2021.09.20
트리의 개념 Tree  (0) 2021.09.19
원형 큐 Circular Queue  (0) 2021.09.17
큐 Queue  (0) 2021.09.16
스택 Stack  (0) 2021.09.14

댓글