슬라이드 1

Similar documents
5.스택(강의자료).key

슬라이드 1

Microsoft PowerPoint - 07-chap05-Stack.ppt

4장

o 스택 (stack) ~ 쌓아놓은더미 1. 스택의개요 - 2 -

03장.스택

03장.스택.key

슬라이드 1

Chapter 4. LISTS

Microsoft PowerPoint - ch07_스택 [호환 모드]

chap 5: Trees

untitled

Chapter 4. LISTS

06장.리스트

Microsoft PowerPoint - 08-chap06-Queue.ppt

Lab 3. 실습문제 (Single linked list)_해답.hwp

Microsoft PowerPoint - 08-Queue.ppt

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint - 제5장-스택의응용.pptx

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

슬라이드 1

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

03_queue

슬라이드 1

리스트 (list), 선형리스트 (linear list): 순서를가진항목들의모임 집합 : 항목간의순서의개념이없음 L = n ( item0, item1,..., item -1) l 리스트의예 l 요일 : ( 일요일, 월요일,, 토요일 ) l 한글자음의모임 : ( ㄱ, ㄴ

chap x: G입력

Chapter 06. 스택(Stack)

1장. 리스트

05_tree

슬라이드 1

chap01_time_complexity.key

K&R2 Reference Manual 번역본

중간고사 (자료 구조)

chap x: G입력

원형연결리스트에대한설명중틀린것은 모든노드들이연결되어있다 마지막에삽입하기가간단한다 헤더노드를가질수있다 최종노드포인터가 NULL이다 리스트의 번째요소를가장빠르게찾을수있는구현방법은무엇인가 배열 단순연결리스트 원형연결리스트 이중연결리스트 단순연결리스트의노드포인터 가마지막노드를

11장 포인터

untitled

Chap 6: Graphs

11장 포인터

chap x: G입력

Lab 5. 실습문제 (Double linked list)-1_해답.hwp

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

Chapter 4. LISTS

Algorithms

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

ABC 10장

Contents v 학습목표 자료구조큐에대한개념을스택과비교하여이해한다. 큐의특징과연산방법에대해알아본다. 순차표현방법을이용한큐와연결표현방법을이용한큐를구현해본다. 큐의응용방법을알아본다. v 내용 큐 큐의구현 큐의응용 2/74

컴파일러

Microsoft PowerPoint - 제4장-스택과큐.pptx

Microsoft PowerPoint - ch07 - 포인터 pm0415

Microsoft PowerPoint - chap05-제어문.pptx

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

Microsoft Word - FunctionCall

데이터구조 (Chapter 3: Stacks and Queues) 2011 년봄학기 숙명여자대학교이과대학멀티미디어과학과박영호

슬라이드 1

02장.배열과 클래스

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

Microsoft PowerPoint - chap04-연산자.pptx

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

04장.큐

untitled

Microsoft PowerPoint - 제11장 포인터(강의)

<4D F736F F F696E74202D20C1A637C0E52DB0EDB1DEBFACB0E1B8AEBDBAC6AE2E >

슬라이드 1

PowerPoint 프레젠테이션

슬라이드 1

Data structure: Assignment 1 Seung-Hoon Na October 1, Assignment 1 Binary search 주어진 정렬된 입력 파일이 있다고 가정하자. 단, 파일내의 숫자는 공백으로 구 분, file내에 숫자들은

슬라이드 1

Chapter 08. 트리(Tree)

C 언어 강의노트

08장.트리

Microsoft PowerPoint - 제11장 포인터

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

7장

Algorithms

1장. 유닉스 시스템 프로그래밍 개요

<4D F736F F F696E74202D20C0DAB7E1B1B8C1B65FC3E2BCAEBCF6BEF7>

슬라이드 1

금오공대 컴퓨터공학전공 강의자료

슬라이드 1

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - chap06-2pointer.ppt

4장

슬라이드 1

(Microsoft Word - \301\337\260\243\260\355\273\347.docx)

untitled

OCW_C언어 기초

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

Microsoft PowerPoint - chap10-함수의활용.pptx

C프로-3장c03逞풚

3장. Hello World

본 강의에 들어가기 전

제 11 장포인터 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

Microsoft PowerPoint - chap-11.pptx

PowerPoint 프레젠테이션

Transcription:

CHAP 5: 스택

스택이란? 스택 (stack): 쌓아놓은더미

스택의특징 후입선출 (LIFO:Last-In First-Out): 가장최근에들어온데이터가가장먼저나감. D C B C B C B C B A A A A

스택의구조 요소 (element) C 스택상단 (top) B A 스택하단 (bottom)

스택추상데이터타입 (ADT) 객체 : n 개의 element 형의요소들의선형리스트 연산 : create() ::= 스택을생성한다. is_empty(s) ::= 스택이비어있는지를검사한다. is_full(s) ::= 스택이가득찼는가를검사한다. push(s, e) ::= 스택의맨위에요소 e 를추가한다. pop(s) ::= 스택의맨위에있는요소를삭제한다. peek(s) ::= 스택의맨위에있는요소를삭제하지않고반환한다.

스택의연산 push(): 스택에데이터를추가 pop(): 스택에서데이터를삭제 push(a) push(b) push(c) C pop() B B B A A A A 초기상태

스택의연산 is_empty(s): 스택이공백상태인지검사 is_full(s): 스택이포화상태인지검사 create(): 스택을생성 peek(s): 요소를스택에서삭제하지않고보기만하는연산 ( 참고 )pop 연산은요소를스택에서완전히삭제하면서가져온다.

스택의용도 입력과역순의출력이필요한경우 에디터에서되돌리기 (undo) 기능 함수호출에서복귀주소기억 1 20 int main() { int i=3; sub1(i);... sub2 PC=150 b=5 100 150 int sub1(int a) { int j=5; sub2(j);... main PC=1 sub1 PC=20 a=3 main i=3 sub1 PC=20 a=3 j=5 main i=3 sub1 PC=20 a=3 j=5 main i=3 main i=3 200 void sub2(int b) {... 시스템스택 시스템스택 시스템스택 시스템스택 시스템스택

배열을이용한스택의구현 1 차원배열 stack[ ] 스택에서가장최근에입력되었던자료를가리키는 top 변수 가장먼저들어온요소는 stack[0] 에, 가장최근에들어온요소는 stack[top] 에저장 스택이공백상태이면 top 은 -1 4 4 4 top 3 3 3 2 2 top 2 1 1 1 0-1 공백상태 top 0-1 0-1 포화상태

is_empty, is_full 연산의구현 is_empty(s) is_full(s) if top = -1 then return TRUE else return FALSE if top = (MAX_STACK_SIZE-1) then return TRUE else return FALSE 4 3 2 1 4 3 2 1 top 0 0-1 공백상태 top -1 포화상태

push 연산 push(s, x) if is_full(s) then error "overflow" else top top+1 stack[top] x 4 3 2 1 0 top 4 3 2 1 0 top

pop 연산 pop(s, x) if is_empty(s) then error "underflow" else e stack[top] top top-1 return e 4 3 2 1 0 top 4 3 2 1 0 top

C 언어구현 typedef int element; typedef struct { element stack[max_stack_size]; int top; StackType; // 스택초기화함수 void init(stacktype *s) { s->top = -1; // 공백상태검출함수 int is_empty(stacktype *s) { return (s->top == -1); // 포화상태검출함수 int is_full(stacktype *s) { return (s->top == (MAX_STACK_SIZE-1)); 배열의요소는 element 타입으로선언 관련데이터를구조체로묶어서함수의파라미터로전달

// 삽입함수 void push(stacktype *s, element item) { if( is_full(s) ) { fprintf(stderr," 스택포화에러 \n"); return; else s->stack[++(s->top)] = item; // 삭제함수 element pop(stacktype *s) { if( is_empty(s) ) { fprintf(stderr, " 스택공백에러 \n"); exit(1); else return s->stack[(s->top)--]; // 피크함수 element peek(stacktype *s) { if( is_empty(s) ) { fprintf(stderr, " 스택공백에러 \n"); exit(1); else return s->stack[s->top];

연결된스택 연결된스택 (linked stack): 연결리스트를이용하여구현한스택 장점 : 크기가제한되지않음 단점 : 구현이복잡하고삽입이나삭제시간이오래걸린다. 4 3 9 top 2 1 9 7 top 7 0 3 3 NULL

연결된스택정의 typedef int element; typedef struct StackNode { element item; struct StackNode *link; StackeNode; 요소의타입 노드의타입 typedef struct { StackNode *top; LinkedStackType; 연결된스택의관련데이터 9 top 7 3 NULL

연결된스택에서 push 연산 top C B A NULL temp (2) D (1) // 삽입함수 void push(linkedstacktype *s, element item) { StackNode *temp=(stacknode *)malloc(sizeof(stacknode)); if( temp == NULL ){ else{ fprintf(stderr, " 메모리할당에러 \n"); return; temp->item = item; temp->link = s->top; s->top = temp;

연결된스택에서 pop 연산 top // 삭제함수 element pop(linkedstacktype *s) { if( is_empty(s) ) { else{ temp fprintf(stderr, " 스택이비어있음 \n"); exit(1); StackNode *temp=s->top; int item = temp->item; s->top = s->top->link; free(temp); C B A NULL return item;

스택의응용 : 괄호검사 괄호의종류 : 대괄호 ( [, ] ), 중괄호 ( {, ), 소괄호 ( (, ) ) 조건 1. 왼쪽괄호의개수와오른쪽괄호의개수가같아야한다. 2. 같은괄호에서왼쪽괄호는오른쪽괄호보다먼저나와야한다. 3. 괄호사이에는포함관계만존재한다. 잘못된괄호사용의예 (a(b) a(b)c) a{b(c[d]ef)

스택을이용한괄호검사 if( ( i==0 ) && (j==0 ) 비교 ( ( 비교 오류 ( ( ( ( ( ( ( ( { A [ (i+1 ) ]=0; 비교비교비교성공 ( [ { { [ { ( [ [ { { {

알고리즘 알고리즘의개요 문자열에있는괄호를차례대로조사하면서왼쪽괄호를만나면스택에삽입하고, 오른쪽괄호를만나면스택에서 top 괄호를삭제한후오른쪽괄호와짝이맞는지를검사한다. 이때, 스택이비어있으면조건 1 또는조건 2 등을위배하게되고괄호의짝이맞지않으면조건 3 등에위배된다. 마지막괄호까지를조사한후에도스택에괄호가남아있으면조건 1 에위배되므로 0( 거짓 ) 을반환하고, 그렇지않으면 1( 참 ) 을반환한다.

괄호검사알고리즘 check_matching(expr) while ( 입력 expr 의끝이아니면 ) ch expr 의다음글자 switch(ch) case '(': case '[': case '{': ch 를스택에삽입 break case ')': case ']': case ']': if ( 스택이비어있으면 ) then 오류 else 스택에서 open_ch 를꺼낸다 break if (ch 와 open_ch 가같은짝이아니면 ) then 오류보고 if( 스택이비어있지않으면 ) then 오류 왼쪽괄호이면스택에삽입 오른쪽괄호이면스택에서삭제, 비교

괄호검사프로그램 // int check_matching(char *in) { StackType s; char ch, open_ch; int i, n = strlen(in); init(&s); for (i = 0; i < n; i++) { ch = in[i]; switch(ch){ case '(': case '[': push(&s, ch); break; case '{':

case ')': case ']': case '': if(is_empty(&s)) return FALSE; else { open_ch = pop(&s); if ((open_ch == '(' && ch!= ')') (open_ch == '[' && ch!= ']') (open_ch == '{' && ch!= '')) { return FALSE; break; if(!is_empty(&s)) return FALSE; return TRUE; int main() { if( check_matching("{ A[(i+1)]=0; ") == TRUE ) printf(" 괄호검사성공 \n"); else printf(" 괄호검사실패 \n");

수식의계산 수식의표기방법 : 전위 (prefix), 중위 (infix), 후위 (postfix) 중위표기법 전위표기법 후위표기법 2+3*4 +2*34 234*+ a*b+5 +5*ab ab*5+ (1+2)+7 +7+12 12+7+ 컴퓨터에서의수식계산순서 중위표기식 -> 후위표기식 -> 계산 2+3*4 -> 234*+ -> 14 모두스택을사용 먼저후위표기식의계산법을알아보자

후위표기식의계산 수식을왼쪽에서오른쪽으로스캔하여피연산자이면스택에저장하고연산자이면필요한수만큼의피연산자를스택에서꺼내연산을실행하고연산의결과를다시스택에저장 ( 예 ) 82/3-32*+ 토큰 8 8 스택 [0] [1] [2] [3] [4] [5] [6] 2 8 2 / 4 3 4 3-1 3 1 3 2 1 3 2 * 1 6 + 7

0 1 2 3 8 8 2 / 3-0 1 2 3 8 8 2 / 3-2 0 1 2 3 4 8 2 / 3 - 피연산자 -> 삽입피연산자 -> 삽입연산자 -> 8/2=4 삽입 0 1 2 3 4 8 2 / 3-0 1 2 3 1 8 2 / 3-0 1 2 3 1 8 2 / 3-3 피연산자 -> 삽입연산자 -> 4-1=1 삽입종료 -> 전체연산결과 =1

후위표기식계산알고리즘 스택 s 를생성하고초기화한다. for 항목 in 후위표기식 do if ( 항목이피연산자이면 ) push(s, item) if ( 항목이연산자 op 이면 ) then second pop(s) first pop(s) result first op second // op 는 +-*/ 중의하나 push(s, result) final_result pop(s);

// 후위표기수식계산함수 eval(char exp[]) { int op1, op2, value, i=0; int len = strlen(exp); char ch; StackType s; init(&s); for( i=0; i<len; i++){ ch = exp[i]; if( ch!= '+' && ch!= '-' && ch!= '*' && ch!= '/' ){ value = ch - '0'; // 입력이피연산자이면 push(&s, value); else{ // 연산자이면피연산자를스택에서제거 op2 = pop(&s); op1 = pop(&s); switch(ch){ // 연산을수행하고스택에저장 return pop(&s); case '+': push(&s,op1+op2); break; case '-': push(&s,op1-op2); break; case '*': push(&s,op1*op2); break; case '/': push(&s,op1/op2); break;

중위표기식 -> 후위표기식 중위표기와후위표기 중위표기법과후위표기법의공통점은피연산자의순서는동일 연산자들의순서만다름 ( 우선순위순서 ) -> 연산자만스택에저장했다가출력하면된다. 2+3*4 -> 234*+ 알고리즘 피연산자를만나면그대로출력 연산자를만나면스택에저장했다가스택보다우선순위가낮은연산자가나오면그때출력 왼쪽괄호는우선순위가가장낮은연산자로취급하며, 무조건스택에저장 오른쪽괄호가나오면스택에서왼쪽괄호위에쌓여있는모든연산자를출력

( a + b ) * c (

( a + b ) * c a (

( a + b ) * c + a (

( a + b ) * c + a b (

( a + b ) * c a b +

( a + b ) * c a b + *

( a + b ) * c a b + c *

( a + b ) * c a b + c *

infix_to_postfix(exp) 스택 s 를생성하고초기화 while (exp 에처리할문자가남아있으면 ) ch 다음에처리할문자 switch (ch) case 연산자 : while ( peek(s) 의우선순위 ch 의우선순위 ) do e pop(s) e 를출력 push(s, ch); break; case 왼쪽괄호 : push(s, ch); break; case 오른쪽괄호 : e pop(s); while( e 왼쪽괄호 ) do e 를출력 e pop(s) break; case 피연산자 : ch 를출력 break; while( not is_empty(s) ) do e pop(s) e 를출력

프로그램 // 중위표기수식 -> 후위표기수식 void infix_to_postfix(char exp[]) { int i = 0; char ch, top_op; int len = strlen(exp); StackType s; init(&s); for (i = 0; i<len; i++) { ch = exp[i]; // 연산자이면 switch (ch) { // 스택초기화 case '+': case '-': case '*': case '/': // 연산자 // 스택에있는연산자의우선순위가더크거나같으면출력 while (!is_empty(&s) && (prec(ch) <= prec(peek(&s)))) push(&s, ch); break; printf("%c", pop(&s)); case '(':// 왼쪽괄호 push(&s, ch); break;

프로그램 case ')':// 오른쪽괄호 top_op = pop(&s); // // 왼쪽괄호를만날때까지출력 while( top_op!= '(' ){ printf("%c", top_op); top_op = pop(&s); break; default: printf("%c", ch); break; // 피연산자 while(!is_empty(&s) ) // 스택에저장된연산자들출력 printf("%c", pop(&s)); main() { infix_to_postfix("(2+3)*4+9");

미로탐색문제 체계적인방법필요 현재의위치에서가능한방향을스택에저장해놓았다가막다른길을만나면스택에서다음탐색위치를꺼낸다. 1 1 1 1 1 1 1 1 1 1 입구 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 1 0 1 1 0 0 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 출구 1 0 1 0 1 m 0 1 0 1 1 0 1 0 0 0 0 1 0 x 1 1 1 1 1 1 1 1 1 1

미로탐색알고리즘 스택 s 과출구의위치 x, 현재생쥐의위치를초기화 while( 현재의위치가출구가아니면 ) do 현재위치를방문한것으로표기 성공 ; if( 현재위치의위, 아래, 왼쪽, 오른쪽위치가아직방문되지않았고갈수있으면 ) then 그위치들을스택에 push if( is_empty(s) ) then 실패 else 스택에서하나의위치를꺼내어현재위치로만든다 ;

미로프로그램 #define MAX_STACK_SIZE 100 #define MAZE_SIZE 6 typedef struct StackObjectRec { short r; short c; StackObject; StackObject stack[max_stack_size]; int top = -1; StackObject here={1,0, entry={1,0; char maze[maze_size][maze_size] = { {'1', '1', '1', '1', '1', '1', {'e', '0', '1', '0', '0', '1', {'1', '0', '0', '0', '1', '1', {'1', '0', '1', '0', '1', '1', {'1', '0', '1', '0', '0', 'x', {'1', '1', '1', '1', '1', '1', ;

미로프로그램 void pushloc(int r, int c) { if( r < 0 c < 0 ) return; if( maze[r][c]!= '1' && maze[r][c]!= '.' ){ StackObject tmp; tmp.r = r; tmp.c = c; push(tmp); void printmaze(char m[maze_size][maze_size]) {

미로프로그램 void printstack() { int i; for(i=5;i>top;i--) printf(" for(i=top;i>=0;i--) \n"); printf(" (%01d,%01d) \n", stack[i].r, stack[i].c); printf("-------\n");

미로프로그램 void main() { int r,c; here = entry; printmaze(maze); printstack(); while ( maze[here.r][here.c]!='x' ){ printmaze(maze); r = here.r; c = here.c; maze[r][c] = '.'; pushloc(r-1,c); pushloc(r+1,c); pushloc(r,c-1); pushloc(r,c+1);

미로프로그램 printstack(); if( isempty() ){ else printf(" 실패 \n"); return; here = pop(); printmaze(maze); printstack(); getch(); printf(" 성공 \n");