[자료구조] 큐(Queue)

2022. 4. 10. 10:14· 자료구조
선입 선출의 자료구조.

 

[큐의 종류]

 

  • 배열을 기반으로 구현된 큐
  • 리스트를 기반으로 구현된 큐

 

 

[배열을 기반으로 구현된 큐] = 원형 큐

 

※ 스택과 큐는 차이가 별로 없어보이지만 구현방법에는 차이가 크다 !

 

▶ ADT 

필요한 기능 : 큐 초기화, 큐 비었는지 확인, 큐에 데이터 넣기, 큐에서 데이터 꺼내기, 다음에 나올 데이터 들여다보기

void QueueInit(Queue * pq);
int QIsEmpty(Queue * pq);
void Enqueue(Queue * pq, Data data); //데이터 삽입
Data Dequeue(Queue * pq); //데이터 삭제
Data QPeek(Queue * pq);

 

▶ 배열을 기반으로 구현된 리스트의 문제점

★ 위 그림에서 front의 index를 1씩 더하여 Dequeue 하고 rear을 참조하여 Enqueue 한다

문제점 : 배열의 끝에 너무 빨리 도달하게 된다 ! 

→ 해결 : 데이터의 출입이 반복되면 앞부분은 비어 있기 때문에 R을 앞부분으로 이동시킨다 = 원형 큐 구현!!

 

▶ 원형 큐란?

<특징>

  • 배열을 꽉 채우면 front와 rear를 가지고 텅빈 경우와 꽉 찬 경우를 구분할수 없으므로 배열을 한칸 남겨둔다.
  • Enqueue 연산 시 rear가 가리키는 위치를 한 칸 이동시킨 다음에 rear가 가리키는 위치에 데이터를 저장한다.
  • Dequeue 연산 시 front가 가리키는 위치를 한 칸 이동시킨 다음에 front가 가리키는 위치에 저장된 데이터를 삭제한다.

원형 큐가 꽉찬 경우 : rear가 가리키는 위치의 앞을 front가 가리킨다

원형 큐가 텅빈 경우 : 초기 상태와 같이 front 와 rear가 동일한 위치를 가리킨다

 

▶ 구현

 

  • 원형 큐를 의미하는 구조체 - 그림의 front, rear, 값을 저장할 배열
typedef struct _cQueue
{
	int front;
	int rear;
	Data queArr[100];
} CQueue;



  • 원형 큐의 핵심 함수 -> 큐의 다음 위치에 해당하는 배열의 인덱스 값을 반환하는 함수 (front와 rear의 회전을 돕는다)
int NextPosIdx (int pos)
{
    if(pos == 99) // 끝에 도달하면
    	return 0; // 처음으로 돌아간다
    else
    	return pos+1;

 

  • ADT의 구현
void QueueInit(Queue * pq) //큐 초기화
{
	pq->front = 0;
	pq->rear = 0;
}

int QIsEmpty(Queue * pq) 
{
	if(pq->front == pq->rear) //큐 비어 있으면 front rear 위치 같음
		return TRUE;
	else
		return FALSE;
}

int NextPosIdx(int pos) // 가장 중요한 함수
{
	if(pos == QUE_LEN-1)
		return 0;
	else
		return pos+1;
}

void Enqueue(Queue * pq, Data data)
{
	if(NextPosIdx(pq->rear) == pq->front) //큐가 꽉찬경우
	{
		printf("Queue Memory Error!");
		exit(-1);
	}

	pq->rear = NextPosIdx(pq->rear);
	pq->queArr[pq->rear] = data;
}

Data Dequeue(Queue * pq)
{
	if(QIsEmpty(pq))//큐가 빈경우
	{
		printf("Queue Memory Error!");
		exit(-1);
	}

	pq->front = NextPosIdx(pq->front);
	return pq->queArr[pq->front];
}

Data QPeek(Queue * pq)
{
	if(QIsEmpty(pq))
	{
		printf("Queue Memory Error!");
		exit(-1);
	}

	return pq->queArr[NextPosIdx(pq->front)];
}

 

<특징>

Enqueue

→ rear 값을 먼저 한칸 옮기고 데이터를 삽입한다

Dequeue

→ front 값을 먼저 한칸 옮기고 데이터를 삭제한다

QIsEmpty

→ 데이터가 비어 있으면 rear 값과 front 값이 같고, 데이터가 꽉 차있으면 front값이 rear값보다 한칸 앞서있다

 


[연결리스트를 기반으로 구현된 큐] 

 

※ 배열기반 큐는 스택과 큐의 구현차이가 컸지만 연결리스트 기반 큐는 스택과 큐의 구현차이가 적다

 

▶ ADT 

필요한 기능 : 큐 초기화, 큐 비었는지 확인, 큐에 데이터 넣기, 큐에서 데이터 꺼내기, 다음에 나올 데이터 들여다보기

void QueueInit(Queue * pq);
int QIsEmpty(Queue * pq);
void Enqueue(Queue * pq, Data data); //데이터 삽입
Data Dequeue(Queue * pq); //데이터 삭제
Data QPeek(Queue * pq);

▶ 구현 목표

 

▶ 구현

 

  • 원형 큐를 의미하는 구조체 - 맨 앞과 맨 뒤를 가리킴
typedef struct _lQueue
{
	Node * front;
	Node * rear;
} LQueue;

 

  • ADT의 구현
void QueueInit(Queue * pq)
{
	pq->front = NULL;
	pq->rear = NULL;
}

int QIsEmpty(Queue * pq)
{
	if(pq->front == NULL)
		return TRUE;
	else
		return FALSE;
}

void Enqueue(Queue * pq, Data data) //데이터 삽입
{
	Node * newNode = (Node*)malloc(sizeof(Node));
	newNode->next = NULL;
	newNode->data = data;

	if(QIsEmpty(pq))
	{
		pq->front = newNode;
		pq->rear = newNode;
	}
	else
	{
		pq->rear->next = newNode; //새로운 노드를 연결하고
		pq->rear = newNode; //rear를 새로운 노드로 옮김
	}
}

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; //맨 마지막 데이터 삭제의 경우 pq->front->next가 null임
	free(delNode);
	return retData;
}

Data QPeek(Queue * pq)
{
	if(QIsEmpty(pq))
	{
		printf("Queue Memory Error!");
		exit(-1);
	}

	return pq->front->data;
}

 

<특징>

Enqueue

→ 큐가 비어있지 않으면 맨 마지막 데이터의 next에 새로운 노드를 연결하고 rear를 새로운 노드로 바꿈

Dequeue

→  front를 한칸 뒤로 댕기고 그 전에 front 였던걸 삭제함 ( 여기서 맨 마지막 데이터를 삭제하는 경우 맨 마지막 데이터의 next는 null이므로 front에 null이 저장됨

 

▶ 시뮬레이션에서 사용되는 큐

시뮬레이션 : 특정 상황에 놓인 복잡한 문제의 해결을 위해서 실제와 비슷한 상황을 연출하는것

시뮬레이션이라는 주제에서 큐가 자주 활용됨

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

[자료구조] 우선순위 큐(Priority Queue)와 힙(Heap)  (0) 2022.04.24
[자료구조] 트리(Tree)  (0) 2022.04.17
[자료구조] 덱(Deque)  (0) 2022.04.10
[자료구조] 스택 (Stack)  (0) 2022.04.02
[자료구조] 연결 리스트 (Linked list)  (0) 2022.04.01
'자료구조' 카테고리의 다른 글
  • [자료구조] 트리(Tree)
  • [자료구조] 덱(Deque)
  • [자료구조] 스택 (Stack)
  • [자료구조] 연결 리스트 (Linked list)
생선묵김치찌개
생선묵김치찌개
생선묵김치찌개
준혁's 코딩 연구기록
생선묵김치찌개
전체
오늘
어제
  • 분류 전체보기 (96)
    • Java (5)
    • Spring Boot (3)
    • 자료구조 (8)
    • 네트워크 (4)
    • 데이터베이스 (4)
    • 기술적 고민 (17)
      • Side Match (13)
      • 자리나따 (4)
    • C++ (3)
    • Algorithm (4)
    • PS 연습 (38)
    • 잡동사니 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 완전탐색
  • 브루트 포스
  • Stream
  • 열혈 자료구조
  • 양방향 연결 리스트
  • 해커톤
  • DN
  • 이진트리
  • 파일 업로드
  • sentry
  • 원형 연결 리스트
  • 알고리즘
  • 배열 리스트
  • open api
  • 자료구조
  • 스택
  • backend
  • CPP
  • dp
  • 트리
  • 재귀
  • 수식트리
  • ㄱ
  • 스프링
  • aws rds
  • 큐
  • 예외처리
  • 단순 연결 리스트
  • 백준
  • 백준 골드

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
생선묵김치찌개
[자료구조] 큐(Queue)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.