stack SANGJI University Kwangman Ko kkmansangji ac kr

  • Slides: 59
Download presentation
스택(stack) SANGJI University Kwangman Ko kkman@sangji. ac. kr

스택(stack) SANGJI University Kwangman Ko kkman@sangji. ac. kr

1. 스택의 개요 o 스택(stack) ~ 쌓아놓은 더미 Stack & Queue kkman@sangji. ac. kr

1. 스택의 개요 o 스택(stack) ~ 쌓아놓은 더미 Stack & Queue kkman@sangji. ac. kr -2 -

스택의 연산 o 삽입(push), 삭제(pop) push(A) push(B) push(C) pop() C A B B B

스택의 연산 o 삽입(push), 삭제(pop) push(A) push(B) push(C) pop() C A B B B A A A 초기상태 Stack & Queue kkman@sangji. ac. kr -5 -

스택의 용도 o 입력과 역순의 출력이 필요한 경우 ~ 에디터에서 되돌리기(undo) 기능 ~ 함수호출에서

스택의 용도 o 입력과 역순의 출력이 필요한 경우 ~ 에디터에서 되돌리기(undo) 기능 ~ 함수호출에서 복귀주소 기억 1 20 100 150 200 int main() { int i=3; sub 1(i); . . . } sub 2 PC=200 b=5 int sub 1(int a) { int j=5; sub 2(j); . . . } void sub 2(int b) {. . . } main PC=1 시스템 스택 Stack & Queue sub 1 PC=150 a=3 j=5 sub 1 PC=151 a=3 j=5 main PC=20 i=3 시스템 스택 sub 1 PC=100 a=3 main PC=20 i=3 시스템 스택 kkman@sangji. ac. kr main PC=21 i=3 시스템 스택 -9 -

is_empty, is_full 연산 is_full(S) is_empty(S) if top = -1 then return TRUE else return

is_empty, is_full 연산 is_full(S) is_empty(S) if top = -1 then return TRUE else return FALSE 4 4 3 3 2 2 1 1 0 0 top -1 공백상태 Stack & Queue if top = (MAX_STACK_SIZE-1) then return TRUE else return FALSE top -1 포화상태 kkman@sangji. ac. kr - 11 -

push 연산 push(S, x) if is_full(S) then error "overflow" else top←top+1 stack[top]←x 4 4

push 연산 push(S, x) if is_full(S) then error "overflow" else top←top+1 stack[top]←x 4 4 3 3 2 2 1 0 Stack & Queue top 1 0 kkman@sangji. ac. kr - 12 -

pop 연산 pop(S, x) if is_empty(S) then error "underflow" else e←stack[top] top←top-1 return e

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 Stack & Queue top 4 3 2 1 0 kkman@sangji. ac. kr top - 13 -

연결된 스택 정의 typedef int element; typedef struct Stack. Node { element item; struct

연결된 스택 정의 typedef int element; typedef struct Stack. Node { element item; struct Stack. Node *link; } Stacke. Node; typedef struct { Stack. Node *top; } Linked. Stack. Type; Stack & Queue kkman@sangji. ac. kr - 15 -

연결된 스택에서 push 연산 C top (1) B (2) temp Stack & Queue A

연결된 스택에서 push 연산 C top (1) B (2) temp Stack & Queue A D kkman@sangji. ac. kr NULL - 16 -

void push(Linked. Stack. Type *s, element item) { Stack. Node *temp= (Stack. Node *)malloc(sizeof(Stack.

void push(Linked. Stack. Type *s, element item) { Stack. Node *temp= (Stack. Node *)malloc(sizeof(Stack. Node)); if( temp == NULL ){ fprintf(stderr, "메모리 할당에러n"); return; } else{ temp->item = item; temp->link = s->top; s->top = temp; } } Stack & Queue kkman@sangji. ac. kr - 17 -

연결된 스택에서 pop 연산 top temp Stack & Queue C B kkman@sangji. ac. kr

연결된 스택에서 pop 연산 top temp Stack & Queue C B kkman@sangji. ac. kr A NULL - 18 -

element pop(Linked. Stack. Type *s) { if( is_empty(s) ) { fprintf(stderr, "스택이 비어있음n"); exit(1);

element pop(Linked. Stack. Type *s) { if( is_empty(s) ) { fprintf(stderr, "스택이 비어있음n"); exit(1); } else{ Stack. Node *temp=s->top; int item = temp->item; s->top = s->top->link; free(temp); return item; } } Stack & Queue kkman@sangji. ac. kr - 19 -

8 2 / 3 - 8 2 3 3 3 2 2 2 1

8 2 / 3 - 8 2 3 3 3 2 2 2 1 1 0 8 피연산자-> 삽입 Stack & Queue 0 2 8 피연산자-> 삽입 kkman@sangji. ac. kr / 3 - 1 0 4 연산자-> 8/2=4 삽입 - 23 -

후위 표기식 계산 알고리즘 스택 s를 생성하고 초기화한다. for 항목 in 후위표기식 do if

후위 표기식 계산 알고리즘 스택 s를 생성하고 초기화한다. for 항목 in 후위표기식 do if (항목이 피연산자이면) push(s, item) if (항목이 연산자 op이면) then second ← pop(s) first ← pop(s) result ← first op second push(s, result) final_result ← pop(s); Stack & Queue kkman@sangji. ac. kr - 25 -

eval(char exp[]) { int op 1, op 2, value, i=0; int len = strlen(exp);

eval(char exp[]) { int op 1, op 2, value, i=0; int len = strlen(exp); char ch; Stack. Type s; init(&s); for( i=0; i<len; i++){ ch = exp[i]; if( ch != '+'&& ch != '-' && ch != '*' && ch != '/' ){ value = ch - '0'; // 입력이 피연산자이면 push(&s, value); } else{ //연산자이면 피연산자를 스택에서 제거 op 2 = pop(&s); op 1 = pop(&s); switch(ch){ //연산을 수행하고 스택에 저장 case '+': push(&s, op 1+op 2); break; case '-': push(&s, op 1 -op 2); break; case '*': push(&s, op 1*op 2); break; case '/': push(&s, op 1/op 2); break; } } } return pop(&s); } Stack & Queue kkman@sangji. ac. kr - 26 -

( a + b ) * c ( Stack & Queue kkman@sangji. ac. kr

( a + b ) * c ( Stack & Queue kkman@sangji. ac. kr - 28 -

( a + b ) * c a ( Stack & Queue kkman@sangji. ac.

( a + b ) * c a ( Stack & Queue kkman@sangji. ac. kr - 29 -

( a + b ) * c + a ( Stack & Queue kkman@sangji.

( a + b ) * c + a ( Stack & Queue kkman@sangji. ac. kr - 30 -

( a + b ) * c + a b ( Stack & Queue

( a + b ) * c + a b ( Stack & Queue kkman@sangji. ac. kr - 31 -

( a Stack & Queue + b ) * c a kkman@sangji. ac. kr

( a Stack & Queue + b ) * c a kkman@sangji. ac. kr b + - 32 -

( a + b ) * c a b + * Stack & Queue

( a + b ) * c a b + * Stack & Queue kkman@sangji. ac. kr - 33 -

( a + b ) * c a b + c * Stack &

( a + b ) * c a b + c * Stack & Queue kkman@sangji. ac. kr - 34 -

( a Stack & Queue + b ) * c a kkman@sangji. ac. kr

( a Stack & Queue + b ) * c a kkman@sangji. ac. kr b + c * - 35 -

infix_to_postfix(exp) 스택 s를 생성하고 초기화 while (exp에 처리할 문자가 남아 있으면) ch ← 다음에

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를 출력 Stack & Queue kkman@sangji. ac. kr - 36 -

Chap. 6 : 큐(queue) SANGJI University Kwangman Ko kkman@sangji. ac. kr

Chap. 6 : 큐(queue) SANGJI University Kwangman Ko kkman@sangji. ac. kr

3 3 4 2 5 2 1 6 1 7 0 front rear 5

3 3 4 2 5 2 1 6 1 7 0 front rear 5 A 6 7 0 front rear (a) 초기상태 Stack & Queue 4 (b) A 삽입 kkman@sangji. ac. kr - 43 -

rear 3 2 B 1 rear 4 A 7 0 front 5 2 6

rear 3 2 B 1 rear 4 A 7 0 front 5 2 6 1 4 5 B front (c) B 삽입 Stack & Queue 3 6 0 7 (d) A 삭제 kkman@sangji. ac. kr - 44 -

큐의 연산 // 공백 상태 검출 함수 int is_empty(Queue. Type *q) { return (q->front

큐의 연산 // 공백 상태 검출 함수 int is_empty(Queue. Type *q) { return (q->front == q->rear); } // 포화 상태 검출 함수 int is_full(Queue. Type *q) { return ((q->rear+1)%MAX_QUEUE_SIZE == q->front); }

// 삽입 함수 void enqueue(Queue. Type *q, element item) { if( is_full(q) ) error("큐가

// 삽입 함수 void enqueue(Queue. Type *q, element item) { if( is_full(q) ) error("큐가 포화상태입니다"); q->rear = (q->rear+1) % MAX_QUEUE_SIZE; q->queue[q->rear] = item; } // 삭제 함수 element dequeue(Queue. Type *q) { if( is_empty(q) ) error("큐가 공백상태입니다"); q->front = (q->front+1) % MAX_QUEUE_SIZE; return q->queue[q->front]; } Stack & Queue kkman@sangji. ac. kr - 47 -

연결된 큐에서의 삽입 front A B rear temp C D rear front A NULL

연결된 큐에서의 삽입 front A B rear temp C D rear front A NULL B C D NULL

연결된 큐에서의 삭제 rear front A temp A Stack & Queue C B NULL

연결된 큐에서의 삭제 rear front A temp A Stack & Queue C B NULL rear front B D C kkman@sangji. ac. kr D NULL - 50 -

덱(DEQUE) o 덱(deque) ~ Double-Ended QUEue ~ 큐의 전단(front)와 후단(rear)에서 모두 삽입과 삭제가 가능

덱(DEQUE) o 덱(deque) ~ Double-Ended QUEue ~ 큐의 전단(front)와 후단(rear)에서 모두 삽입과 삭제가 가능 add_rear add_front delete_rear delete_front get_rear 전단(front) 후단(rear)

덱의 연산 rear front C A front(dq, A) A B rear front A B

덱의 연산 rear front C A front(dq, A) A B rear front A B front(dq, C) B front D rear A ddd_rear(dq, B) C A ddd_rear(dq, D) rear front Stack & Queue rear front B D delete_front(dq) rear front A B delete_rear(dq) kkman@sangji. ac. kr - 53 -

덱의 구현 o 이중 연결리스트를 이용한 구현 ~ 양쪽끝에서 삽입, 삭제가 가능 typedef int

덱의 구현 o 이중 연결리스트를 이용한 구현 ~ 양쪽끝에서 삽입, 삭제가 가능 typedef int element; // 요소의 타입 typedef struct Dlist. Node { element data; struct Dlist. Node *llink; struct Dlist. Node *rlink; } Dlist. Node; // 노드의 타입 typedef struct Deque. Type { Dlist. Node *head; Dlist. Node *tail; } Deque. Type; // 덱의 타입

덱에서의 삽입 연산 Stack & Queue kkman@sangji. ac. kr - 55 -

덱에서의 삽입 연산 Stack & Queue kkman@sangji. ac. kr - 55 -

void add_rear(Deque. Type *dq, element item) { Dlist. Node *new_node = create_node(dq->tail, item, NULL);

void add_rear(Deque. Type *dq, element item) { Dlist. Node *new_node = create_node(dq->tail, item, NULL); if( is_empty(dq)) dq->head = new_node; else dq->tail->rlink = new_node; dq->tail = new_node; }

void add_front(Deque. Type *dq, element item) { Dlist. Node *new_node = create_node(NULL, item, dq->head);

void add_front(Deque. Type *dq, element item) { Dlist. Node *new_node = create_node(NULL, item, dq->head); if( is_empty(dq)) dq->tail = new_node; else dq->head->llink = new_node; dq->head = new_node; } Stack & Queue kkman@sangji. ac. kr - 57 -

// 전단에서의 삭제 element delete_front(Deque. Type *dq) { element item; Dlist. Node *removed_node; if

// 전단에서의 삭제 element delete_front(Deque. Type *dq) { element item; Dlist. Node *removed_node; if (is_empty(dq)) error("공백 덱에서 삭제"); else { removed_node = dq->head; // 삭제할 노드 item = removed_node->data; // 데이터 추출 dq->head = dq->head->rlink; // 헤드 포인터 변경 free(removed_node); // 메모리 공간 반납 if (dq->head == NULL) // 공백상태이면 dq->tail = NULL; else // 공백상태가 아니면 dq->head->llink=NULL; } return item; }