1 / 37

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

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

Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 5장. 스택(stack) 1절. 스택 2절. 배열을 이용한 스택 3절. 연결 리스트를 이용한 스택 4절. 스택응용 – 괄호검사 5절. 스택 응용 – 수식의 후위 표기식 변환 6절. 스택 응용 – 수식의 후위 표기식 계산 이 완 직 (wjlee@pnu.ac.kr) 2010년 1학기

  2. 1. 스택 • 데이터를 삭제(pop)할 때에는 가장 최근에 삽입한 데이터를 꺼내는 구조 • 가장 최근에 들어온 데이터가 가장 먼저 나가기 때문에 후입선출(後入先出), LIFO(Last-In, First-Out: 라이포 리포), LCFS(Last-Come, First-Served)라고 한다.

  3. 1. 스택 • 스택의 연산

  4. 1. 스택 • Push 연산 • Pop 연산

  5. 2. 배열을 이용한 스택 • 최대 MAX_STACK_SIZE개의 원소를 저장할 수 있는 스택을 1차원 배열로 선언 char stack[MAX_STACK_SIZE]; //스택에 원소를 저장하기 위한 배열 int top = -1 //스택 초기화 int isEmpty() { return (top == -1); }

  6. void push(StackObject item) { //스택이 가득 차 있는지를 확인한다 if( isFull() ) { printf("stack is full, can not add element.\n"); } else { //TOP 인덱스를 증가한 후 현재 TOP에 원소 삽입 stack[++top] = item; } } 2. 배열을 이용한 스택 int isFull() { return (top == (MAX_STACK_SIZE-1)); }

  7. StackObject pop() { //스택이 비어 있는지 확인한다 if( isEmpty() ) { printf("stack is empty\n"); } else { //현재 TOP에서 원소를 삭제한 후 TOP 인덱스를 감소시킨다 return stack[top--]; } } 2. 배열을 이용한 스택

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

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

  10. 3. 연결 리스트를 이용한 스택 • 스택의 push 및 pop 과정

  11. 3. 연결 리스트를 이용한 스택 • 스택을 구현하기 위한 정의 • typedef struct StackNode { • element data; • //다음 노드를 가리키는 포인터변수 • struct StackNode *link; • } StackNode; • push 함수 • void push(element item) • { • StackNode* temp=(StackNode *)malloc(sizeof(StackNode));//❶ • temp->data = item; • temp->link = top; //❷ • top = temp; //❸ • }

  12. 3. 연결 리스트를 이용한 스택 ❶ 우선 새로운 노드 공간을 확보해야 한다. ❷ 새로운 노드가 현재 상태의 첫 노드를 가리키게 한다. ❸ top이 새로운 노드를 가리키게 한다.

  13. 3. 연결 리스트를 이용한 스택 • pop 함수 구현 • 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; • } • }

  14. 3. 연결 리스트를 이용한 스택 ❶ top 포인터를 temp에 백업해둔다 ❷ top이 다음 노드를 가리키게 한다. ❸ 이전 top 노드의 공간을 반납한다. 반납 후에 이전 top 데이터를 리턴해야 하므로 top 데이터를 미리 복사해놓는다.

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

  16. 4. 스택 응용 – 괄호 검사 • 수식은 연산자(Operator)와 피연산자(Operand)로 구성 • 수식의 예 연산자 X = A / B - C 피연산자 • 수식에서 연산자의 우선 순위 • 단항 – (unary minus), ! • *, /, % • +, - • 프로그래머는 괄호를 사용하여 연산자의 우선 순위를 변경할 수 있다. • 예) X = (A/(B-C))

  17. 4. 스택 응용 – 괄호 검사 • 수식의 괄호 검사 응용 • 괄호 (중괄호([,]) 대괄호({,}) 포함) 검사의 규칙 • 수식의 괄호 검사에 스택을 이용 • 괄호는 가까운 것끼리 쌍을 이룸, 즉마지막의 열린(왼쪽) 괄호를 가장 먼저 닫아야 함 • 왼쪽 괄호들을 만나면 스택에 push • 오른쪽 괄호를 만나면 스택에서 pop한 괄호와 쌍을 맞추어 봄 ❶ 왼쪽 괄호의 개수와 오른쪽 괄호의 개수가 같아야 한다. ❷ 같은 괄호에서 왼쪽 괄호는 오른쪽 괄호보다 먼저 나와야 한다. ❸ 괄호 사이에는 포함 관계만 존재한다.

  18. 4. 스택 응용 – 괄호 검사 • 괄호 검사 알고리즘 • 수식을 왼쪽에서 오른쪽으로 하나씩 읽으면서 괄호 검사 • 왼쪽 괄호를 만나면 • 스택에 push한다. • 오른쪽 괄호를 만나면 • 스택을 pop하여 현재 (오른쪽) 괄호와 비교한다. • 같은 종류가 아니면 오류! • 스택을 pop할 수 없으면(비워있으면), 오류! • 수식의 끝에 도달 • 스택이 비워 있지 않으면 오류! • 스택이 비워있으면 성공!

  19. 4. 스택 응용 – 괄호 검사

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

  21. 5. 스택 응용 – 수식의 후위 표기식 변환 • 수식을 표현하는 3 가지 방법 • 전위 표기식(prefix notation) • 연산자를 앞에 표기하고 그 뒤에 피연산자를 표기하는 방법 • +AB • 중위 표기식(infix notation) • 연산자를 피연산자의 가운데 표기하는 방법 • A+B • 후위 표기식(postfix notation) • 연산자를 피연산자 뒤에 표기하는 방법 • AB+

  22. 5. 스택 응용 – 수식의 후위 표기식 변환 • infix=> prefix 변환 ❶ 수식의 각 연산자에 대해서 우선순위에 따라 괄호를 사용하여 다시 표현한다. ❷ 각 연산자를 그에 대응하는 왼쪽 괄호의 앞으로 이동시킨다. ❸ 괄호를 제거한다.

  23. 5. 스택 응용 – 수식의 후위 표기식 변환 • infix=> postfix 표기식 변환 ❶ 수식의 각 연산자에 대해서 우선순위에 따라 괄호를 사용하여 다시 표현한다. ❷ 각 연산자를 그에 대응하는 오른쪽 괄호의 뒤로 이동시킨다. ❸ 괄호를 제거한다.

  24. 5. 스택 응용 – 수식의 후위 표기식 변환 • 컴퓨터에서 수식 계산을 위한 postfix notation으로 변환 • 괄호를 사용하지 않아도 된다(이미 연산자의 우선 순위가 고려). • 수식 계산이 용이하다(postfix에서 즉시 연산을 수행). • infix를 postfix로 변환하는 알고리즘 • 피연산자는 출력 • 연산자는 현재 연산자와 스택의 연산자를 비교 • 현재 연산자 순위가 높으면 => 현재 연산자를 스택에 push • 그렇지 않으면 => 스택의 연산자를 pop하여 출력 • 수식이 끝나면 • 스택의 모든 연산자를 pop하여 출력한다.

  25. 5. 스택 응용 – 수식의 후위 표기식 변환 a + b * c로부터 abc * + 를 생성하려면 다음과 같이 연산자를 스택에 저장해 두었다가 출력해야 한다. 피연산자를 만나면 출력한다.

  26. 5. 스택 응용 – 수식의 후위 표기식 변환 연산자는 스택에 저장해둔다. 피연산자를 만나면 출력한다.

  27. 5. 스택 응용 – 수식의 후위 표기식 변환 연산자를 만나면 이 시점에서 ‘*’를 스택에 push해야 할것인지, 아니면 ‘+’를 pop해서 출력할 것인 지를 결정하여야 한다. => ‘*’ 순위 > ‘+’ 순위 이므로 ‘*’ 를 스택에 저장한다. 피연산자를 만나면 출력한다.

  28. 5. 스택 응용 – 수식의 후위 표기식 변환 이제 입력 수식이 더 이상 없으므로 스택에 남아 있는 연산자들을 모두 출력하여 다음을 얻는다.

  29. 5. 스택 응용 – 수식의 후위 표기식 변환 • 괄호를 포함한 infix => postfix로 변환 • 변환 알고리즘 • 연산자/피연산자: 앞의 알고리즘과 동일 • 왼쪽 괄호: 무조건 스택에 push • 주의) 스택 내의 왼쪽 괄호: 가장 낮은 우선순위 연산자로 취급 • 오른쪽 괄호: • 스택 안의 왼쪽 괄호를 만날때 까지 • 스택 안의 연산자를 pop하여 출력 • 스택 안의 왼쪽 괄호를 만남 • 왼쪽 괄호와 현재의 오른쪽 괄호를 모두 제거(출력하지는 않음)

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

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

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

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

  34. 6. 스택 응용-수식의 후위 표기식 계산 • postfix에서 수식 계산 • postfix의 장점 때문에 컴퓨터의 수식 계산은 아래와 같은 두 단계로 수행 • infix=> postfix 변환 • postfix=> 수식 연산 • postfix에서 연산 수행 알고리즘 • 피연산자: 스택에 push • 연산자: 스택에서 두 개의 피연산자를 pop • operand2 = pop(statck); • operand1 = pop(statck); • [operand1 연산자 operand2] 계산 수행 • 결과를 다시 stack에 push • 수식 종료 • 스택에서 pop한 피연산자가 최종 연산 결과가 됨 • 이때 스택에 최종 결과를 제외한 다른 피연산자가 존재해서는 안된다. (수식 오류)

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

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

More Related