Post on 17-Jun-2020
자료구조 & 알고리즘
스택과 큐(Stack and Queue)
자료구조 & 알고리즘
스택과 큐(Stack and Queue)
Seo, Doo-Ok
Clickseo.comclickseo@gmail.com
목 차
스택 개념 및 구현
큐 개념 및 구현
2
스 택
스택 개념 및 구현
스택 구현
스택 응용
큐 개념 및 구현
3
스 택
스택(Stack)
후입선출(LIFO, Last-In-First-Out)
4
DCBA
Top
삭제
POP
삽입
PUSH
입 력 : A B C D
5
스택 구현
알고리즘
순차 자료 구조, / 연결 자료 구조
스택 구현 (1/6)
스택 구현 : 순차 자료구조
순차 자료구조인 1차원 배열을 이용하여 구현• 스택 크기 : 배열의 크기
• 스택에 저장된 원소의 순서 : 배열 원소의 첨자
• 변수 top : 스택에 저장된 마지막 원소에 대한 첨자 저장
– 공백 상태 : top = -1 (초기값)
– 포화 상태 : top = n - 1
6
장점 : 순차 자료구조인 1차원 배열을 이용하여 쉽게 구현
단점 : 정적 배열을 사용하므로 스택의 크기 변경의 어려움
n 번째 원소
...
두 번째 원소
첫 번째 원소
stack 스택의 구현
첫 번째 원소 두 번째 원소 ... n 번째 원소
[0] [1] [n – 1]...
스택 구현 (2/6)
스택 구현 : 연결 자료구조
단순 연결 리스트를 이용하여 구현• 스택의 원소 : 단순 연결 리스트의 노드
– 스택 원소의 순서 : 노드의 링크 필드(포인터)로 연결
– push : 항상 리스트의 첫 번째 노드로 삽입
– pop : 항상 리스트의 마지막 노드를 삭제
• 변수 top : 단순 연결 리스트의 마지막 노드를 가리키는 포인터 변수
– 초기 상태 : top = NULL
7
n 번째 원소
...
두 번째 원소
첫 번째 원소
stack 스택의 구현
n 번째 원소 링크
data link
top
첫 번째 원소 링크
두 번째 원소 링크
... ...
스택 구현 (3/6)
스택 구현 : 알고리즘
초기의 빈 스택 생성 알고리즘
• 스택에 최대로 저장할 수 있는 원소 개수를 배열 크기로 하여 1차원 배열을 선언
• 저장된 원소가 없는 빈 스택 이므로 top 을 -1로 초기화
8
stack_Create()
stack[n]; // 크기가 n 인 1차원 배열 생성
top -1;
end stack_Create()
스택 구현 (4/6)
스택 구현 : 알고리즘
스택의 데이터 삽입 알고리즘 : PUSH
스택의 데이터 삭제 알고리즘 : POP
9
push(S, data)
if (top + 1 = n) then stack_isFull;
else S(++top) data;
end push()
pop(S)
if (top = -1) then estack_isEmpty;
else return S(top--);
end pop()
스택 구현 (5/6)
스택 구현 : 알고리즘
스택의 공백 상태 검사 알고리즘
스택의 포화 상태 검사 알고리즘
10
stack_isEmpty(S)
if(top = -1) then return true;
else return false;
end stack_isEmpty()
stack_isFull(S)
if(top + 1 = n) then return true;
else return false;
end stack_isFull()
스택 구현 (6/6)
스택 구현 : 알고리즘
스택 검색 알고리즘
• 스택에서 Stack[top]에 있는 원소를 검색하여 반환하는 연산
11
stack_peek(S)
if (top = -1) then stack_isEmpty;
else return S(top);
end stack_peek()
12
스택 구현
연결 자료 구조
C Programming Language
스택 구현 : 연결 리스트 - C (1/6)
13
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 Stack.h
#ifndef STACK_SIZE#define STACK_SIZE 10
#endif
#ifndef ELEMENT#define ELEMENT
typedef int element;#endif
#ifndef __STACK_H_#define __STACK_H_typedef struct _stacktype{
element stack[STACK_SIZE];int top;
}StackType;#endif
StackType *stack_Create(void);void stack_Destroy(StackType *);void push(StackType *, element);element pop(StackType *);void stack_Output(StackType *);
스택 구현 : 연결 리스트 - C (2/6)
14
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 main.c (1/2)
#include <stdio.h>#include <stdlib.h>#include “Stack.h"
int main(){
int num, data;StackType *s = stack_Create();
while(1){
system("cls");printf("\n ### 스택 구현 : 1차원 배열 ### \n\n");printf("1) 데이터 삽입 : PUSH \n");printf("2) 데이터 삭제 : POP \n");printf("3) 전체 출력 \n");printf("4) 프로그램 종료 \n\n");printf("메뉴 선택 : ");scanf("%d", &num);fflush(stdin);
스택 구현 : 연결 리스트 - C (3/6)
15
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 main.c (2/2)
switch(num){
case 1 : printf("\n 삽입 할 데이터 입력 : ");scanf("%d", &data); fflush(stdin);push(s, data);break;
case 2 : printf("삭제 된 데이터 : %3d \n“, pop(s) );break;
case 3 : stack_Output(s); break;case 4 : printf("프로그램 종료... \n");
return 0;default : printf("잘못 선택 하셨습니다. \n");
}system("pause");
}
stack_Destroy(s);
return 0;}
스택 구현 : 연결 리스트 - C (4/6)
16
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 stack.c (1/3)
#include <stdio.h>#include <stdlib.h>
#include "stack.h"
StackType *stack_Create(void){
StackType *s = (StackType *)malloc(sizeof(StackType));if(s == NULL){
printf("스택 생성 실패!!! \n");return NULL;
}
s->top = -1;
return s;}
void stack_Destroy(StackType *s){
free(s);
return;}
스택 구현 : 연결 리스트 - C (5/6)
17
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 stack.c (2/3)
void push(StackType *s, element data){
if(s->top + 1 == STACK_SIZE){
printf("스택이 꽉 찼네요!!! \n");return;
}
s->stack[++s->top] = data;
return;}
element pop(StackType *s){
if (s->top == -1){
printf("스택이 비어 있네요!!! \n");return EOF;
}
return s->stack[s->top--];}
스택 구현 : 연결 리스트 - C (6/6)
18
프로그램 예제 : 순차 자료구조를 이용한 스택의 구현 stack.c (3/3)
void stack_Output(StackType *s){
int i;
printf("\n STACK [ ");
for(i=0; i <= s->top; i++)printf("%3d", s->stack[i] );
printf(" ]\n");
return;
}
19
스택 응용
다양한 스택 응용
스택 응용 (1/3)
다양한 스택의 응용
역순 문자열
백 스페이스 키
진법의 변환
수식의 괄호 검사
수식의 후위 표기법 변환
후위 표기법을 이용한 수식 연산
시스템 스택(System Stack)
• 함수의 호출과 복귀 순서를 스택의 LIFO 구조를 응용하여 관리
20
스택 응용 (2/3)
후위 표기법 변환 : 알고리즘
21
infix_to_postfix(exp)while (true) do{
symbol ← getSymbol(exp);case{
symbol = operand : print(symbol);symbol = operator :
while (op(stack[top]) >= op(symbol)) doprint(pop(Stack));
push(Stack, symbol);symbol = “(“ : push(Stack, symbol);symbol = ")" :
while (stack[top] ≠ “(” ) doprint(pop(Stack));
pop(Stack);symbol = NULL : return;
}}
end infix_to_postfix()
( 3 * 5 ) – ( 6 / 2 )
(변환) 3 5 * 6 2 / -
스택 응용 (3/3)
후위 표기법 연산 : 알고리즘
22
evalPostfix(exp)while (true) do{
symbol ← getSymbol(exp); case{
symbol = operand : push(Stack, symbol);symbol = operator :
operand2 ← pop(Stack)); operand1 ← pop(Stack)); res ← operand1 op(symbol) operand2;push(Stack, res);
symbol = NULL : return;}
} end evalPostfix()
3 5 * 6 2 / - : (결과) 12
큐
스택 개념 및 구현
큐 개념 및 구현
큐 구현
큐 응용
23
큐
큐(Queue)
선입선출(FIFO, First-In First-Out)
• 리스트의 한쪽 끝에서 삽입 작업이 이루어지고 반대쪽 끝에서 삭제 작업이
이루어져서 삽입된 순서대로 삭제되는 구조
24
A B C DFront Rear
입 력 : A B C D
25
큐 구현
알고리즘
순차 자료 구조
큐 구현 : 순차 자료 구조 (1/9)
선형 큐(Linear Queue)
연속된 삽입, 삭제에 의한 오른쪽 이동
26
10 20 30 40
Front
-1Rear
3
10 20 30 400 3Remove
10 20 30 401 3Remove
10 20 30 40 501 4Add
10 20 30 40 50 60 70 803 7Final
큐 구현 : 순차 자료 구조 (2/9)
선형 큐
선형 큐의 잘못된 포화상태 인식• 큐에서 삽입과 삭제를 반복하면서 아래와 같은 상태일 경우, 앞부분에 빈자리가
있지만 rear = n - 1 상태이므로 포화상태로 인식하고 더 이상의 삽입을 수행하지
않는다.
27
10 20 30 40 50 60 70 803 7Final
Front Rear
Rear + 1 == Queue_SIZE
큐 구현 : 순차 자료 구조 (3/9)
선형 큐
선형 큐의 잘못된 포화상태 인식의 해결 방법 #1• 저장된 원소들을 배열의 앞부분으로 이동
– 순차자료에서의 이동 작업은 연산이 복잡하여 효율성이 떨어짐
28
50 60 70 80 50 60 70 80-1 3
Front Rear
10 20 30 40 50 60 70 803 7Final
Front Rear
큐 구현 : 순차 자료 구조 (4/9)
원형 큐(Circular Queue)
선형 큐의 잘못된 포화상태 인식의 해결 방법 #2
29
90 20 30 40 50 60 70 803 0Front Rear
10 20 30 40 50 60 70 803 7Final
Front Rear
Add
90
20
30
4050
60
70
80
07
(Rear + 1) % Queue_SIZE
큐 구현 : 순차 자료 구조 (5/9)
원형 큐 : 문제점
문제점• 빈 큐와 꽉 찬 큐의 판정불가 : Front = Rear + 1• 별도의 Count 변수 유지
30
40
0
1
40
0
1
3 3Front Rear
4 3Front Rear
Remove
90
20
30
40
60
70
80
0
190
20
30
40100
60
70
80
0
1
5 3Front Rear
5 4Front Rear
Add
큐 구현 : 순차 자료 구조 (6/9)
선형 큐 구현 : 알고리즘
초기 공백 선형 큐 생성 알고리즘
• 큐에 최대로 저장할 수 있는 원소 개수를 배열의 크기로 하는 1차원 배열을 선언
• 저장된 원소가 없는 공백 큐이므로 front와 rear는 -1로 초기화
31
queue_Create()
Q[n]; // 크기가 n 인 1차원 배열 생성
front -1;
rear -1;
end queue_Create()
큐 구현 : 순차 자료 구조 (7/9)
선형 큐 구현 : 알고리즘
선형 큐의 삽입 알고리즘 : enQueue
선형 큐의 삭제 알고리즘 : deQueue
32
enQueue(Q, data)if (Q->rear + 1 = n) then queue_isFull;
else
Q[++rear] data;
end enQueue()
deQueue(Q)if (Q->front = Q->rear) then queue_isEmpty;
else
return Q[++front];
end deQueue()
큐 구현 : 순차 자료 구조 (8/9)
선형 큐 구현 : 알고리즘
선형 큐의 공백 검사 알고리즘
선형 큐의 포화 상태 검사 알고리즘
33
queue_isEmpty(Q)
if(Q->front = Q->rear) then return true;
else return false;
end queue_isEmpty()
queue_isFull(Q)
if(Q->rear + 1 = n) then return true;
else return false;
end queue_isFull()
큐 구현 : 순차 자료 구조 (9/9)
선형 큐 구현 : 알고리즘
선형 큐 검색 알고리즘
• 큐에서 검색은 원소 중에서 가장 먼저 들어와 있는 원소, 즉 Q[front+1]에 있는
원소를 검색하여 반환하는 연산이다.
34
queue_Peek()
if(Q->front = Q->rear) then queue_isFull;
else
return Q[front + 1];
end queue_Peek()
35
큐 구현
순차 자료 구조
C Programming Language
큐 구현 : 선형 큐 - C (1/6)
36
프로그램 예제 : 순차 자료구조로 구현한 큐 Queue.h
#ifndef QUEUE_SIZE#define QUEUE_SIZE 10
#endif
#ifndef ELEMENT#define ELEMENT
typedef int element;#endif
#ifndef __QUEUE_H#define __QUEUE_Htypedef struct _queueType{
element queue[QUEUE_SIZE];int front, rear;
}QueueType;
QueueType *queue_Create();void queue_Destroy(QueueType *);void enQueue(QueueType *Q, element item);element deQueue(QueueType *Q);void queue_Print(QueueType *Q);#endif
큐 구현 : 선형 큐 - C (2/6)
37
프로그램 예제 : 순차 자료구조로 구현한 큐 main.c (1/2)
#include <stdio.h>#include <stdlib.h>#include "Queue.h"
int main(){
int num, data;QueueType *q = queue_Create();
while(1){
system("cls");printf("\n ### 큐 구현 : 1차원 배열 ### \n\n");printf("1) 데이터 삽입 : enQueue \n");printf("2) 데이터 삭제 : deQueue \n");printf("3) 전체 출력 \n");printf("4) 프로그램 종료 \n\n");printf("메뉴 선택 : ");scanf("%d", &num);
큐 구현 : 선형 큐 - C (3/6)
38
프로그램 예제 : 순차 자료구조로 구현한 큐 main.c (2/2)
switch(num){
case 1 : printf("\n 삽입 할 데이터 입력 : ");scanf("%d", &data); fflush(stdin);enQueue(q, data);break;
case 2 : printf("삭제 된 데이터 : %3d \n", deQueue(q) );break;
case 3 : queue_Print(q); break;case 4 : printf("프로그램 종료... \n");
return 0;default : printf("잘못 선택 하셨습니다. \n");
fflush(stdin);}system("pause");
}queue_Destroy(q);return 0;
}
큐 구현 : 선형 큐 - C (4/6)
39
프로그램 예제 : 순차 자료구조로 구현한 큐 Queue.c (1/3)
#include <stdio.h>#include <stdlib.h>#include "Queue.h"
QueueType *queue_Create(){
QueueType *Q;
Q = (QueueType *)malloc(sizeof(QueueType));if(Q == NULL){
printf(“Queue 생성 실패!!! \n”);return NULL;
}
Q->front = -1;Q->rear = -1;
return Q;}
void queue_Destroy(QueueType *Q){
free(Q);}
큐 구현 : 선형 큐 - C (5/6)
40
프로그램 예제 : 순차 자료구조로 구현한 큐 Queue.c (2/3)
void enQueue(QueueType *Q, element item){
if(Q->rear + 1 >= QUEUE_SIZE)
return;
Q->queue[++Q->rear] = item;
return;
}
element deQueue(QueueType *Q){
if(Q->front == Q->rear)
return -1;
return Q->queue[++Q->front];
}
큐 구현 : 선형 큐 - C (6/6)
41
프로그램 예제 : 순차 자료구조로 구현한 큐 Queue.c (3/3)
void queue_Print(QueueType *Q){
int i;
printf("\n Queue : [");
for(i = Q->front+1; i <= Q->rear; i++)printf("%3d", Q->queue[i]);
printf(" ] \n");
return;}
42
큐 구현
알고리즘
연결 자료 구조
큐 구현 : 연결 자료 구조 (1/3)
연결 큐(Linked Queue)
순자 자료구조로 구현한 큐의 문제점• 크기가 제한되어 큐의 길이를 마음대로 사용할 수 없다.
• 원소가 없을 때에도 항상 그 크기를 유지하고 있어야 하므로 메모리 낭비
연결 큐의 구조
• 데이터 필드와 링크 필드를 가진 노드로 구성– 첫 번째 노드를 가리키는 front 포인터
– 마지막 노드를 가리키는 rear 포인터
– 연결 큐의 초기 상태(공백 큐) : front와 rear를 널(NULL) 포인터로 설정
43
2000 3000 4000 NULL
1000 번지 2000 번지 3000 번지 4000 번지
1000front 4000 rear
큐 구현 : 연결 자료 구조 (2/3)
덱(Deque, Double-ended Queue)
큐의 양쪽 끝에서 삽입과 삭제가 모두 발생할 수 있는 큐• 스택과 큐의 성질을 모두 가지고 있는 자료구조
44
A B C DFront Rear
큐 구현 : 연결 자료 구조 (3/3)
덱 구현
이중 연결 리스트 구조를 이용한 덱의 구현
45
NULL
Llink
front rear
data Rlink Llink data Rlink
NULL
Llink data Rlink
46
큐 응용
다양한 큐의 응용
큐 응용
다양한 큐의 응용
회문(Palindromes)
• 앞에서 읽거나 뒤에서 읽으나 똑같은 단어나 문장
• 예 : 기러기, 토마토, 소주 만병만 주소 등
운영체제의 작업 큐• 프로세스 스케줄링 큐(Process Scheduling Queue)
• 프린터 버퍼 큐(Printer Buffer Queue)
시뮬레이션에서의 큐잉 시스템• 모의실험
• 큐잉 이론(Queueing Theory)
• 이벤트 발생시기– 시간 구동 시뮬레이션(Time-Driven Simulation)
– 사건구동 시뮬레이션(Event-Driven Simulation)
47
참고문헌
48
[1] 주우석, “IT CookBook, CㆍC++ 로 배우는 자료구조론”, 한빛아카데미, 2015.
[2] 문병로, “IT CookBook, 쉽게 배우는 알고리즘 - 관계 중심의 사고법”(개정판), 개정판, 한빛아카데미, 2018.
[3] 카사이 아사오, 진명조 역, “C 언어로 배우는 알고리즘 입문”, 한빛미디어, 2005.
[4] 카일 루든(Kyle Loudon), 허욱 역, “Algorithms with C : C로 구현한 알고리즘”, 한빛미디어, 2000.
[5] 이재규, “C 로 배우는 알고리즘 : 개념과 기본 알고리즘”, 도서출판 세화, 2007.
이 강의자료는 저작권법에 따라 보호받는 저작물이므로 무단 전제와 무단 복제를 금지하며,
내용의 전부 또는 일부를 이용하려면 반드시 저작권자의 서면 동의를 받아야 합니다.
Copyright © Clickseo.com. All rights reserved.