PowerPoint 프레젠테이션

Similar documents
chap x: G입력

chap x: G입력

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

untitled

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

Chapter 4. LISTS

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

슬라이드 1

제 3 장 스택과 큐

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

03장.스택.key

슬라이드 1

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

chap 5: Trees

Microsoft PowerPoint - 08-chap06-Queue.ppt

Microsoft PowerPoint - 07-chap05-Stack.ppt

03장.스택

Microsoft PowerPoint - 08-Queue.ppt

4장

슬라이드 1

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

슬라이드 1

03_queue

Chapter 4. LISTS

슬라이드 1

Algorithms

04장.큐

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

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

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C4C656D70656C2D5A69762E637070>

K&R2 Reference Manual 번역본

Chapter 4. LISTS

컴파일러

<BCBCB9CCB3AA20C0DAB7E1202D20BDBAC5C3C5A52E687770>

Microsoft PowerPoint - ch08_큐 [호환 모드]

06장.리스트

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

chap01_time_complexity.key

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

2. QUEUE OPERATIONS Initialize the queue Insert to the rear of the queue (also called as Enqueue) Remove (Delete) from the front of the queue (also ca

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

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

Chap 6: Graphs

PowerPoint 프레젠테이션

chap x: G입력

ABC 10장

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

05_tree

PowerPoint 프레젠테이션

08장.트리

<4D F736F F F696E74202D20C0DAB7E1B1B8C1B62D DBFB5BBF3BCF6BEF72DC5E4BFE4C0CFBCF6BEF72E >

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

11장 포인터

Microsoft PowerPoint - logo_3.ppt [호환 모드]

<4D F736F F F696E74202D20C0DAB7E1B1B8C1B65FC3E2BCAEBCF6BEF7>

PowerPoint 프레젠테이션

Microsoft PowerPoint - ch07 - 포인터 pm0415

Microsoft PowerPoint - chap05-제어문.pptx

슬라이드 1

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

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

Chapter 06. 스택(Stack)

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

중간고사 (자료 구조)

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

untitled

슬라이드 1

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

슬라이드 1

7장

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

Microsoft PowerPoint - semantics

11장 포인터

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

슬라이드 1

슬라이드 1

Exercise (10pts) k-친수 일반적으로 k진수(k > 1)는 다음과 같이 표현한다. d0 dn 여기서 di {0,, k 1}. 그리고 d0 dn 은 크기가 d0 k dn k n 인 정수를 표현한다. 이것을 살짝 확장해서 k친수 를 다음과 같이 정의

슬라이드 1

슬라이드 1

PowerPoint Presentation

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

OCaml

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

1장. 리스트

PowerPoint 프레젠테이션

Microsoft PowerPoint - 제3장-배열.pptx

Microsoft PowerPoint - chap04-연산자.pptx

OCW_C언어 기초

제 1 장 기본 개념

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

PowerPoint 프레젠테이션

슬라이드 1

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

02장.배열과 클래스

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

C 언어 강의노트

PowerPoint 프레젠테이션

Homework 2 SNU , Fall 2015 Kwangkeun Yi due: 9/30, 24:00 Exercise 1 (10pts) k- 친수 일반적으로 k 진수 (k > 1) 는다음과같이표현한다. d 0 d n 여기서 d i {0,, k 1}. 그리

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

슬라이드 1

Transcription:

제 3 장. 스택과큐 순서리스트의특별한경우순서리스트 : A=a 0, a 1,, a n-1, n 0 스택 (stack) 톱 (top) 이라고하는한쪽끝에서모든삽입 (push) 과삭제 (pop) 가일어나는순서리스트 스택 S=(a 0,...,a n-1 ): a 0 는 bottom, a n-1 은 top의원소 a i 는원소 a i-1 (0<i<n) 의위에있음 후입선출 (LIFO, Last-In-First-Out) 리스트

스택 (Stack) 원소 A,B,C,D,E 를삽입하고한원소를삭제하는예 E top D top D D C top C C C B top B B B B A top A A A A A top add add add add del

[ 스택추상데이타타입 ] structure Stack objects: 0 개이상의원소를가진유한순서리스트 functions: 모든 stack Stack, item element, max_stack_size positive integer Stack CreateS(max_stack_size) ::= 최대크기가 max_stack_size 인공백스택을생성 Boolean IsFull(stack, max_stack_size) ::= if (stack 의원소수 == max_stack_size) return TRUE else return FALSE Stack Add(stack, item) ::= if (IsFull(stack)) stack_full else stack 의톱에 item 을삽입하고 return Boolean IsEmpty(stack) ::= if (stack == CreateS(max_stack_size)) return TRUE else return FALSE Element Delete(stack) ::= if (IsEmpty(stack)) stack_empty else 스택톱의 item 을제거해서반환

스택추상데이터타입의구현 일차원배열 stack[max_stack_size] 사용 i번째원소는 stack[i-1] 에저장 top은스택의최상위원소를가리킴 ( 초기 : top = -1) Stack CreateS(max_stack_size) ::= #define MAX_STACK_SIZE 100 /* 최대스택크기 */ typedef struct { int key; /* 다른필드 */ element; element stack[max_stack_size]; int top = -1; Boolean IsEmpty(Stack) ::= top < 0; Boolean IsFull(Stack) ::= top >= MAX_STACK_SIZE-1;

스택에대한접근은최상위원소에대한포인터를통해 void add(int *top, element item) { /* 전역 stack에 item을삽입 */ if (*top >= MAX_STACK_SIZE-1) { stack_full(); // 포화상태일때처리 return; stack[++*top] = item; element delete(int *top) { /* stack의최상위원소를반환 */ if (*top == -1) return stack_empty(); /* 오류 key를반환 */ return stack[(*top)--];

큐 (queue) 한쪽끝 (rear) 에서삽입이일어나고그반대쪽끝 (front) 에서삭제가일어나는순서리스트 큐 Q=(a 0,a 1,...,a n-1 ): a 0 는앞 (front) 원소 a n-1 은뒤 (rear) 원소 a i 는 a i-1 (1 i<n) 의뒤에있다고함 선입선출 (FIFO, First-In-First-Out) 리스트 그림 3.4 큐에서의삽입과삭제

[ 큐추상데이타타입 ] structure Queue objects: 0 개이상의원소를가진유한순서리스트 functions: 모든 queue Queue, item element, max_queue_size positive integer Queue CreateQ(max_queue_size) ::= 최대크기가 max_queue_size 인공백큐를생성 Boolean IsFullQ(queue, max_queue_size ) ::= if (queue 의원소수 == max_queue_size) return TRUE else return FALSE Queue AddQ(queue, item) ::= if (IsFull(queue)) queue_full else queue 의뒤에 item 을삽입하고이 queue 를반환 Boolean IsEmptyQ(queue) ::= if (queue == CreateQ(max_queue_size)) return TRUE else return FALSE Element DeleteQ(queue) ::= if (IsEmpty(queue)) return else queue 의앞에있는 item 을제거해서반환

큐의구현 : 1 차원배열이용 변수 front 는큐에서첫원소의위치보다하나작은위치 변수 rear 는큐에서마지막원소의위치 Queue CreateQ(max_queue_size) ::= #define MAX_QUEUE_SIZE 100 /* 큐의최대크기 */ typedef struct { int key; /* 다른필드 */ element; element queue[max_queue_size]; int rear = -1; int front = -1; Boolean IsEmptyQ(queue) ::= front == rear Boolean IsFullQ(queue) ::= rear == MAX_QUEUE_SIZE-1

void addq(int *rear, element item) { /* queue에 item을삽입 */ if (*rear == MAX_QUEUE_SIZE-1) { queue_full(); return; queue[++*rear] = item; element deleteq(int *front, int rear) { /* queue의앞에서원소를삭제 */ if (*front == rear) return queue_empty(); /* 에러 key를반환 */ return queue[++*front];

큐의순차적표현의문제점예 예제 3.2 [ 작업스케쥴링 ]: 운영체제의작업큐 (job queue) 작업들이큐에들어가고나옴에따라큐는점차오른쪽으로이동 결국 rear 값이 MaxSize-1과같아져서큐가포화상태가됨 fro nt -1-1 -1-1 0 0 1 rear Q (1) [1] [2] [3] [4] [5] [6] -1 0 1 2 2 3 3 queue em pty J1 J1 J2 J1 J2 J3 J2 J3 J2 J3 J4 J3 J4 com m ents initial job 1 joins Q job 2 joins Q job 3 joins Q job 1 leaves Q job 4 joins Q job 2 joins Q

순차적큐의문제해결 : 원형큐 배열 queue[maxsize] 를원형으로취급 rear == MaxSize-1 이면 q[0] 가빈경우 q[0] 에삽입 MaxSize 를최대원소로사용하면원형큐는포화와공백모두 front == rear 가됨 이를구분하기위해포화상태는원소수가 MaxSize-1 일경우로함 front == rear 는공백상태로만사용 초기 : front == rear == 0

공백큐 [2] [3] [2] [3] J2 J3 [1] [4] [1] J1 [4] [0] [5] front = 0 rear = 0 [0] [5] front = 0 rear = 3 포화큐 포화큐 [2] [3] [2] [3] J2 J3 J8 J9 [1] J1 J4 [4] [1] J7 [4] J5 J6 J5 [0] [5] front = 0 rear = 5 [0] [5] front = 4 rear = 3

void addq(int *front, int *rear, element item) { /* queue 에 item 을삽입 */ *rear = (*rear+1) % MAX_QUEUE_SIZE; if (front == *rear) queue_full(rear); /* rear 를리세트시키고에러를프린트 */ return; queue[*rear] = item; ------------------------------------------------- void deleteq(int *front, int rear) { element item; /* queue 의 front 원소를삭제하여그것을 item 에놓음 */ if (*front == rear) return queue_empty(); /* queue_empty 는에러키를반환 */ *front = (*front+1) % MAX_QUEUE_SIZE; return queue[*front];

미로문제 스택을응용할수있는예 미로는 1 i m, 1 j p 인이차원배열 maze[m][p] 로표현 1 : 막힌통로, 0 : 열린통로 maze[1][1] 에서출발 maze[m][p] 에출구 입구 이동은 0 이있는사각형만 다음장그림 경계조건을매번검사하지않고미로주위를 1 로만듦, maze[m+2][p+2] 를사용, 첨자 i=0, m+1, j=0, p+1 일때는모두 1 0 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 1 1 0 1 1 1 1 0 출구

미로에서가능한이동 현재의위치 x : maze[i][j] 에서가능한이동 NW N NE [i-1][j-1] [i-1][j] [i-1][j+1] W [i][j-1] X [i][j+1] E [i] [j] [i+1][j-1] [i+1][j] [i+1][j+1] SW S SE 경계위치에서는 8 방향이아님 I = 1 or m, j=1 or m 3 방향, 5 방향만가능한경우

이동할수있는방향들을정의 typedef struct { short int vert; short int horiz; offsets; offsets move[8]; /* 여덟방향이동에대한배열 */ N am e D ir m ove[dir].vert m ove[dir].horiz N NE E SE S SW W NW 0 1 2 3 4 5 6 7-1 -1 0 1 1 1 0-1 0 1 1 1 0-1 -1-1 다음이동위치 : maze[next_row][next_col] next_row = row + move[dir].vert; next_col = col + move[dir].horiz;

경로의탐색 현위치저장후방향선택 : N에서시계방향 잘못된경로의선택시는 backtracking후다른방향시도 시도한경로의재시도방지 mark[m+2][n+2] : 초기치 0 mark[row][col] = 1 /* 한번방문한경우 */ - 경로유지위한스택사용 #define MAX_STACK_SIZE 100 /* 스택의최대크기 */ typedef struct { short int row; short int col; short int dir; element; element stack[max_stack_size]; MAX_STACK_SIZE 는스택에저장되는최대원소수. 미로의각위치는기껏해야한번만방문되므로 mp

initialize a stack to the maze's entrance coordinates and direction to north; while (stack is not empty) { /* 스택의톱에있는위치로이동 */ <rol, col, dir> = delete from top of stack; while (there are more moves from current position) <next_row, next_col> = coordinate of next move; dir = direction of move; if ((next_row == EXIT_ROW) && (next_col == EXIT_COL)) success ; if(maze[next_row][next_col]==0)&&mark[next_row][next_col]==0) { /* 가능하지만아직이동해보지않은이동방향 */ mark[next_row][next_col] = 1; /* 현재의위치와방향을저장 */ add <row, col, dir> to the top of the stack; row = next_row; col = next_col; dir = north; printf("no path found");

void path(void) // 프로그램 3.8 미로탐색함수 {/* 미로를통과하는경로가있으면그경로를출력한다. */ int i, row, col, next_row, next_col, dir, found=false; element position; mark[1][1]=1; top=0; stack[0].row=1; stack[0].col=1; stack[0].dir=1; while (top>-1 &&!found) { position = delete(&top); row = position.row; col = position.col; dir = position.dir; while (dir<8 &&!found) { next_row = row + move[dir].vert; /* dir 방향으로이동 */ next_col = col + move[dir].horiz; if (next_row==exit_row && next_col==exit_col) found = TRUE; else if (!maze[next_row][next_col] &&!mark[next_row][next_col]) { mark[next_row][next_col]) = 1; position.row = row; position.col = col; position.dir = ++dir; add(&top, position); row = next.row; col = next.col; dir = 0; else ++dir;

if (found) { printf("the path is:"); printf("row col"); for (i=0; i<=top; i++) printf("%2d%5d", stack[i].row, stack[i].col"); printf("%2d%5d", row, col); printf("%2d%5d", EXIT_ROW, EXIT_COL); else printf("the maze does not have a path"); path 알고리즘의분석 while 문은스택의크기에종속적이고최대 mp while 안의 while 은최대 8 번즉 O(1) 따라서 O(mp)

수식의계산 토큰 우선순위 결합성 () [] -> 17 LR -- ++ 16 L R & * unary - 15 R L * / % 13 L R + - 12 L R > >= < <= 10 L R ==!= 9 L R && 5 L R 4 L R

수식의표현 - 중위표기 (infix notation) : a * b / c - 후위표기 (postfix notation) : a b * c / 예 ) x = a / b - c + d * e - a * c x = ((((a / b) - c) + (d * e)) - (a * c)) 후위표기 : x = a b / c - d e * a c * - + 괄호사용않함 왼쪽에서오른쪽으로계산 연산자의우선순위없음

후위표기식의연산 : 6 2 / 3-4 2 * + 토큰 스택 Top [0] [1] [2] 6 6 0 2 6 2 1 / 6/2 0 3 6/2 3 1-6/2-3 0 4 6/2-3 4 1 2 6/2-3 4 2 2 * 6/2-3 4*2 1 + 6/2-3+4*2 0

스택과수식의표현방법 #define MAX_STACK_SIZE 100 /* 스택의최대크기 */ #define MAX_EXPR_SIZE 100 /* 수식의최대크기 */ typedef enum {lparen, rparen, plus, minus, times, divide, mod, eos, operand precedence; int stack[max_stack_size]; /* 전역배열 */ char expr[max_expr_size]; /* 입력스트링 */ int eval(void) { /* 전역변수로되어있는후위표기식 expr 을연산한다. \0 은수식의끝을나타낸다. stack 과 top 은전역변수이다. 함수 get_token 은토큰의타입과문자심벌을반환한다. 피연산자는한문자로된숫자임을가정 */ precedence token; char symbol; int op1,op2; int n = 0; /* 수식스트링을위한카운터 */ int top = -1; token = get_token(&symbol, &n);

while (token!= eos) { if (token == operand) add(&top, symbol-'0'); / * 스택삽입 */ else { /* 두피연산자를삭제하여연산을수행후, 결과를스택에삽입 */ op2 = delete(&top); /* 스택삭제 */ op1 = delete(&top); switch(token) { case plus: add(&top, op1+op2); break; case minus: add(&top, op1-op2); break; case times: add(&top, op1*op2); break; case divide: add(&top, op1/op2); break; case mod: add(&top, op1%op2); token = get_token(&symbol, &n); return delete(&top); /* 결과를반환 */

precedence get_token (char *symbol, int * n) { /* 다음토큰을취한다. symbol 은문자표현이며, token 은그것의열거된값으로표현되고, 명칭으로반환된다. */ *symbol = expr[(*n)++]; switch (*symbol) { case '(' : return lparen; case ')' : return rparen; case '+' : return plus; case '-' : return minus; case '/' : return divide; case '*' : return times; case '%' : return mod; case NULL : return eos; default : return operand;

중위표기에서후위표기로의변환 왼쪽에서오른쪽으로조사해가면서후위식을생성 피연산자는바로출력수식에전달 연산자의출력순서는우선순위에의해좌우, 정확한위치를알때까지연산자를스택에저장 예제 3.3 중위표기식 a+b*c를후위표기식으로변환 토큰 스택 Top Output [0] [1] [2] -------------------------------------------- a -1 a + + 0 a b + 0 ab * + * 1 ab c + * 1 abc eos -1 abc*+

예제 3.4 중위표기식 a*(b+c)*d 를후위표기식으로변환 토큰 스택 Top Output [0] [1] [2] -------------------------------------------- a -1 a * * 0 a ( * ( 1 a b * ( 1 ab + * ( + 2 ab c * ( + 2 abc ) * 0 abc+ * * 0 abc+* d * 0 abc+*d eos -1 abc+*d*

연산자의스택킹과언스택킹 왼쪽괄호는스택속에있을때는낮은우선순위, 그외의경우에는높은우선순위 왼쪽괄호는스택에쌓이고, 대응하는오른쪽괄호가나올때에만스택에서삭제 isp(in-stack precedence) 와 icp(incoming precedence) 정의하여스택속의연산자 isp 가새로운연산자의 icp 보다크거나같을때만스택에서삭제 precedence stack[max_stack_size]; /* isp와 icp 배열 -- 인덱스는연산자 lparen, rparen, plus, minus, times, divide, mod, eos의우선순위값 */ static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 ; static int icp[] = {20, 19, 12, 12, 13, 13, 13, 0 ; 예 ) isp[plus] = isp[2] = 12, 오른쪽괄호 19, 왼쪽괄호 0, 20, eos 는 0 n : 수식의토큰수일때, θ(n)

void postfix(void) { /* 수식을후위표기식으로출력한다. 수식문자열, 스택, top 은전역적이다. */ char symbol; precedence token; int n = 0; int top = 0; /* eos 를스택에놓는다. */ stack[0] = eos;

for (token=get_token(&symbol,&n); token!=eos; token=get_token(&symbol,&n)) { if (token == operand) printf("%c", symbol); else if (token == rparen) { while (stack[top]!= lparen) /* 왼쪽괄호가나올때까지 */ print_token(delete(&top)); /* 토큰들을제거해서출력시킴 */ delete(&top); /* 좌괄호를버린다 */ else { //symbol의 isp가 token의 icp보다크거나같으면 symbol을제거하고출력 while (isp[stack[top]] >= icp[token]) print_token(delete(&top)); add(&top, token); // end of for-loop while ((token=delete(&top))!= eos) print_token(token); printf( \n");