이 완 직 ( [email protected] ) 2010 년 1 학기

37
이 이 이 ([email protected] ) 2010 이 1 이이 5 장 . 장장 (stack) 1 장 . 장장 2 장 . 장장장 장장장 장장 3 장 . 장장 장장장장 장장장 장장 4 장 . 장장장장 – 장장장장 5 장 . 장장 장장 – 장장장 장장 장장장 장장 6 장 . 장장 장장 – 장장장 장장 장장장 장장

description

5 장 . 스택 (stack) 1 절 . 스택 2 절 . 배열을 이용한 스택 3 절 . 연결 리스트를 이용한 스택 4 절 . 스택응용 – 괄호검사 5 절 . 스택 응용 – 수식의 후위 표기식 변환 6 절 . 스택 응용 – 수식의 후위 표기식 계산. 이 완 직 ( [email protected] ) 2010 년 1 학기. 1. 스택. 데이터를 삭제 (pop) 할 때에는 가장 최근에 삽입한 데이터를 꺼내는 구조 - PowerPoint PPT Presentation

Transcript of 이 완 직 ( [email protected] ) 2010 년 1 학기

Page 1: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

이 완 직 ([email protected])2010 년 1 학기

5 장 . 스택 (stack)1 절 . 스택2 절 . 배열을 이용한 스택3 절 . 연결 리스트를 이용한 스택4 절 . 스택응용 – 괄호검사5 절 . 스택 응용 – 수식의 후위 표기식

변환6 절 . 스택 응용 – 수식의 후위 표기식

계산

Page 2: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 데이터를 삭제 (pop) 할 때에는 가장 최근에 삽입한 데이터를 꺼내는 구조

• 가장 최근에 들어온 데이터가 가장 먼저 나가기 때문에 후입선출 ( 後入先出 ), LIFO(Last-In, First-Out: 라이포 리포 ), LCFS(Last-Come, First-Served) 라고 한다 .

1. 스택

2

Page 3: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 스택의 연산

1. 스택

3

Page 4: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• Push 연산

1. 스택

4

• Pop 연산

Page 5: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 최대 MAX_STACK_SIZE 개의 원소를 저장할 수 있는 스택을 1차원 배열로 선언

2. 배열을 이용한 스택

5

char stack[MAX_STACK_SIZE]; // 스택에 원소를 저장하기 위한 배열int top = -1 // 스택 초기화

int isEmpty(){

return (top == -1);}

Page 6: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

2. 배열을 이용한 스택

6

void push(StackObject item){

// 스택이 가득 차 있는지를 확인한다if( isFull() ) {

printf("stack is full, can not add element.\n");}else {

//TOP 인덱스를 증가한 후 현재 TOP 에 원소 삽입stack[++top] = item;

}}

int isFull(){ return (top == (MAX_STACK_SIZE-1));}

Page 7: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

2. 배열을 이용한 스택

7

StackObject pop(){

// 스택이 비어 있는지 확인한다if( isEmpty() ) {

printf("stack is empty\n");}else {

// 현재 TOP 에서 원소를 삭제한 후 TOP 인덱스를 감소시킨다return stack[top--];

}}

Page 8: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

8

• [ 예제 5-1] 배열로 스택 구현하기

Page 9: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 스택의 top 을 표현하기 위해서 리스트의 헤드 (head) 포인터를 스택의 top 포인터로 정의한다 .

3. 연결 리스트를 이용한 스택

9

Page 10: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 스택의 push 및 pop 과정

3. 연결 리스트를 이용한 스택

10

Page 11: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 스택을 구현하기 위한 정의

3. 연결 리스트를 이용한 스택

11

typedef struct StackNode {element data;// 다음 노드를 가리키는 포인터변수struct StackNode *link;

} StackNode;

void push(element item) {

StackNode* temp=(StackNode *)malloc(sizeof(StackNode));//❶temp->data = item;temp->link = top; //❷top = temp; //❸

}

• push 함수

Page 12: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

3. 연결 리스트를 이용한 스택

12

❶ 우선 새로운 노드 공간을 확보해야 한다 .

❷ 새로운 노드가 현재 상태의 첫 노드를 가리키게 한다 .

❸ top 이 새로운 노드를 가리키게 한다 .

Page 13: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• pop 함수 구현

3. 연결 리스트를 이용한 스택

13

element pop(){

element item;StackNode* temp=top; //❶if(top == NULL) { // 스택이 비어 있으면

printf(“\n\n Stack is empty !\n”);return 0;

}else {

item = temp->data;top = temp->link; //❷free(temp); //❸return item;

}}

Page 14: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

3. 연결 리스트를 이용한 스택

14

❶ top 포인터를 temp 에 백업해둔다

❷ top 이 다음 노드를 가리키게 한다 .

❸ 이전 top 노드의 공간을 반납한다 . 반납 후에 이전 top 데이터를 리턴해야 하므로 top 데이터를 미리 복사해놓는다 .

Page 15: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• [ 예제 5-2] 연결리스트로 스택 구현하기

15

Page 16: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 수식은 연산자 (Operator) 와 피연산자 (Operand) 로 구성

• 수식의 예

4. 스택 응용 – 괄호 검사

16

• 수식에서 연산자의 우선 순위단항 – (unary minus), !*, /, %+, -

• 프로그래머는 괄호를 사용하여 연산자의 우선 순위를 변경할 수 있다 .

예 ) X = (A/(B-C))

X = A / B - C피연산자

연산자

Page 17: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 수식의 괄호 검사 응용– 괄호 ( 중괄호 ([,]) 대괄호 ({,}) 포함 ) 검사의 규칙

• 수식의 괄호 검사에 스택을 이용– 괄호는 가까운 것끼리 쌍을 이룸 , 즉 마지막의 열린 ( 왼쪽 )

괄호를 가장 먼저 닫아야 함• 왼쪽 괄호들을 만나면 스택에 push• 오른쪽 괄호를 만나면 스택에서 pop 한 괄호와 쌍을 맞추어 봄

4. 스택 응용 – 괄호 검사

17

❶ 왼쪽 괄호의 개수와 오른쪽 괄호의 개수가 같아야 한다 . ❷ 같은 괄호에서 왼쪽 괄호는 오른쪽 괄호보다 먼저 나와야

한다 . ❸ 괄호 사이에는 포함 관계만 존재한다 .

Page 18: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 괄호 검사 알고리즘

– 수식을 왼쪽에서 오른쪽으로 하나씩 읽으면서 괄호 검사

• 왼쪽 괄호를 만나면 – 스택에 push 한다 .

• 오른쪽 괄호를 만나면 – 스택을 pop 하여 현재 ( 오른쪽 ) 괄호와 비교한다 .

» 같은 종류가 아니면 오류 !– 스택을 pop 할 수 없으면 ( 비워있으면 ), 오류 !

• 수식의 끝에 도달– 스택이 비워 있지 않으면 오류 !– 스택이 비워있으면 성공 !

4. 스택 응용 – 괄호 검사

18

Page 19: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

4. 스택 응용 – 괄호 검사

19

Page 20: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• [ 예제 5-3] 괄호 검사하기

20

Page 21: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 수식을 표현하는 3 가지 방법

5. 스택 응용 – 수식의 후위 표기식 변환

21

- 전위 표기식 (prefix notation)연산자를 앞에 표기하고 그 뒤에 피연산자를 표기하는 방법

+AB

- 중위 표기식 (infix notation)연산자를 피연산자의 가운데 표기하는 방법

A+B

- 후위 표기식 (postfix notation)연산자를 피연산자 뒤에 표기하는 방법

AB+

Page 22: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• infix => prefix 변환

5. 스택 응용 – 수식의 후위 표기식 변환

22

❶ 수식의 각 연산자에 대해서 우선순위에 따라 괄호를 사용하여

다시

표현한다 .

❷ 각 연산자를 그에 대응하는 왼쪽 괄호의 앞으로 이동시킨다 .

❸ 괄호를 제거한다 .

Page 23: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• infix => postfix 표기식 변환

5. 스택 응용 – 수식의 후위 표기식 변환

23

❶ 수식의 각 연산자에 대해서 우선순위에 따라 괄호를 사용하여 다시

표현한다 .

❷ 각 연산자를 그에 대응하는 오른쪽 괄호의 뒤로 이동시킨다 .

❸ 괄호를 제거한다 .

Page 24: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 컴퓨터에서 수식 계산을 위한 postfix notation 으로 변환– 괄호를 사용하지 않아도 된다 ( 이미 연산자의 우선 순위가 고려 ).– 수식 계산이 용이하다 (postfix 에서 즉시 연산을 수행 ).

• infix 를 postfix 로 변환하는 알고리즘

– 피연산자는 출력

– 연산자는 현재 연산자와 스택의 연산자를 비교 • 현재 연산자 순위가 높으면 => 현재 연산자를 스택에 push• 그렇지 않으면 => 스택의 연산자를 pop 하여 출력

– 수식이 끝나면• 스택의 모든 연산자를 pop 하여 출력한다 .

5. 스택 응용 – 수식의 후위 표기식 변환

24

Page 25: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

25

a + b * c 로부터 abc * + 를 생성하려면 다음과 같이 연산자를 스택에 저장해 두었다가 출력해야 한다 .

피연산자를 만나면 출력한다 .

Page 26: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

26

연산자는 스택에 저장해둔다 .

피연산자를 만나면 출력한다 .

Page 27: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

27

연산자를 만나면 이 시점에서 ‘ * ’ 를 스택에 push 해야 할 것인지 , 아니면 ‘ +’ 를 pop 해서 출력할 것인 지를 결정하여야 한다 .

=> ‘*’ 순위 > ‘+’ 순위 이므로 ‘ *’ 를 스택에 저장한다 .

피연산자를 만나면 출력한다 .

Page 28: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

28

이제 입력 수식이 더 이상 없으므로 스택에 남아 있는 연산자들을 모두 출력하여 다음을 얻는다 .

Page 29: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• 괄호를 포함한 infix => postfix 로 변환

– 변환 알고리즘

• 연산자 /피연산자 : 앞의 알고리즘과 동일

• 왼쪽 괄호 : 무조건 스택에 push– 주의 ) 스택 내의 왼쪽 괄호 : 가장 낮은 우선순위 연산자로 취급

• 오른쪽 괄호 : – 스택 안의 왼쪽 괄호를 만날때 까지

» 스택 안의 연산자를 pop 하여 출력– 스택 안의 왼쪽 괄호를 만남

» 왼쪽 괄호와 현재의 오른쪽 괄호를 모두 제거 ( 출력하지는 않음 )

5. 스택 응용 – 수식의 후위 표기식 변환

29

Page 30: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

30

Page 31: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

31

Page 32: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

5. 스택 응용 – 수식의 후위 표기식 변환

32

Page 33: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• [ 예제 5-4] 후위 표기식으로 변환

33

Page 34: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

34

Page 35: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

• postfix 에서 수식 계산– postfix 의 장점 때문에 컴퓨터의 수식 계산은 아래와 같은 두

단계로 수행• infix => postfix 변환• postfix => 수식 연산

• postfix 에서 연산 수행 알고리즘– 피연산자 : 스택에 push– 연산자 : 스택에서 두 개의 피연산자를 pop

• operand2 = pop(statck);• operand1 = pop(statck);• [operand1 연산자 operand2] 계산 수행

– 결과를 다시 stack 에 push– 수식 종료

• 스택에서 pop 한 피연산자가 최종 연산 결과가 됨– 이때 스택에 최종 결과를 제외한 다른 피연산자가 존재해서는 안된다 .

( 수식 오류 )

6. 스택 응용 - 수식의 후위 표기식 계산

35

Page 36: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

6. 스택 응용 - 수식의 후위 표기식 계산

36

Page 37: 이 완 직  ( wjlee@pnu.ac.kr ) 2010 년  1 학기

37

• [ 예제 5-5] 후위 표기식의 계산