• 검색 결과가 없습니다.

연결리스트로 구현된 스택

N/A
N/A
Protected

Academic year: 2022

Share "연결리스트로 구현된 스택"

Copied!
44
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

연결리스트로 구현된 스택

[제 12 주]

강 지 훈 [email protected] 충남대학교 컴퓨터공학과

© 2011, J.-H.Kang, CNU

(2)

© 2011, J.-H.Kang, CNU

연결리스트로 구현된 스택

2

연결 리스트로

구현된 스택

(3)

© 2011, J.-H.Kang, CNU

연결리스트로 구현된 스택

3

사용자 관점에서의

스택의 공개함수

(4)

© 2011, J.-H.Kang, CNU

 Class STACK의 공개함수

 STACK 객체의 생성과 소멸

 STACK * STACK_new ()

 void STACK_free (STACK *s)

 STACK 객체의 점검

 boolean STACK_isEmpty (STACK * s)

스택이 empty 이면 TRUE를, 아니면, FALSE를 얻는다.

 boolean STACK_isFull (STACK * s)

스택이 full 이면 TRUE를, 아니면, FALSE를 얻는다.

 STACK 객체에게 행위를 지시

 void STACK_push (STACK * s, ELEMENT e)

스택에 e 를 삽입핚다.

 ELEMENT STACK_pop (STACK * s)

스택의 top에서 원소를 삭제하고 그 값을 얻는다.

연결리스트로 구현된 스택

4

(5)

© 2011, J.-H.Kang, CNU

연결리스트로 구현된 스택

5

스택의 구현

- 연결 리스트로 -

(6)

© 2011, J.-H.Kang, CNU

 Class STACK을 연결리스트로 구현

스택을 아래와 같은 형태로 만들려고 핚다.

연결리스트로 구현된 스택

6

a

0

top

a

1

a

n-1

length

(7)

© 2011, J.-H.Kang, CNU

 Class STACK의 속성들

typedef int ELEMENT ;

// ELEMENT 자료형은 응용에 따라 적절하게 정핚다.

typedef struct s_NODE NODE ; typedef struct s_NODE {

ELEMENT item ; NODE * next ; } NODE ;

typedef struct {

int length ; // 필요 없으면 삭제 가능 NODE * top ;

} STACK ;

연결리스트로 구현된 스택

7

(8)

© 2011, J.-H.Kang, CNU

 생성과 소멸

 STACK * STACK_new () { STACK * s ;

s = NewObject(STACK) ; s->top = NULL ;

return s ; }

 void STACK_free (STACK * s)

{ // There may be some elements in the stack.

FreeLinkedNodes(s->top) ; free(s) ;

}

연결리스트로 구현된 스택

8

(9)

© 2011, J.-H.Kang, CNU

 Push: Before & After

연결리스트로 구현된 스택

9

x

top y

s

length

e

x

top y

s

length

(10)

© 2011, J.-H.Kang, CNU

 Push: Step [0]

void STACK_push (STACK * s, ELEMENT e) {

① NODE * temp = NewObject(NODE) ; if ( STACK_IsFull(s) ) {

……

}

② temp->item = e ;

③ temp->next = s->top ;

④ s->top = temp ; }

연결리스트로 구현된 스택

10

x

top y

s

length

temp

(11)

© 2011, J.-H.Kang, CNU

 Push: Step [1]

void STACK_push (STACK * s, ELEMENT e) {

① NODE * temp = NewObject(NODE) ; if ( STACK_isFull(s) ) {

……

}

② temp->item = e ;

③ temp->next = s->top ;

④ s->top = temp ; }

연결리스트로 구현된 스택

11

x

top y

s

length

temp

(12)

© 2011, J.-H.Kang, CNU

 Push: Step [2]

void STACK_push (STACK * s, ELEMENT e) {

① NODE * temp = NewObject(NODE) ; if ( STACK_isFull(s) ) {

……

}

② temp->item = e ;

③ temp->next = s->top ;

④ s->top = temp ; }

연결리스트로 구현된 스택

12

x

top y

s

length

temp e

① ②

(13)

© 2011, J.-H.Kang, CNU

 Push: Step [3]

void STACK_push (STACK * s, ELEMENT e) {

① NODE * temp = NewObject(NODE) ; if ( STACK_isFull(s) ) {

……

}

② temp->item = e ;

③ temp->next = s->top ;

④ s->top = temp ; }

연결리스트로 구현된 스택

13

x

top y

s

length

temp e ③

① ②

(14)

© 2011, J.-H.Kang, CNU

 Push: Step [4]

void STACK_push (STACK * s, ELEMENT e) {

① NODE * temp = NewObject(NODE) ; if ( STACK_isFull(s) ) {

……

}

② temp->item = e ;

③ temp->next = s->top ;

④ s->top = temp ; }

연결리스트로 구현된 스택

14

x

top y

s

length

temp e ③

① ②

(15)

© 2011, J.-H.Kang, CNU

 Pop: Before & After

연결리스트로 구현된 스택

15

x top

m s

length u

x top

m s

length u

(16)

© 2011, J.-H.Kang, CNU

 Pop: Step [0]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ; return e ; }

연결리스트로 구현된 스택

16

x top

m s

length u

temp e

(17)

© 2011, J.-H.Kang, CNU

 Pop: Step [1]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ; return e ; }

연결리스트로 구현된 스택

17

x top

m s

length u

temp ① e

(18)

© 2011, J.-H.Kang, CNU

 Pop: Step [2]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ; return e ; }

연결리스트로 구현된 스택

18

x top

m s

length u

temp ① e x ②

(19)

© 2011, J.-H.Kang, CNU

 Pop: Step [3]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ; return e;

}

연결리스트로 구현된 스택

19

x top

m s

length u

temp e x ②

(20)

© 2011, J.-H.Kang, CNU

 Pop: Step [4]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ;

⑤ return e;

}

연결리스트로 구현된 스택

20

x top

m s

length u

temp ① e x ②

(21)

© 2011, J.-H.Kang, CNU

 Pop: Step [5]

ELEMENT STACK_pop (STACK * s) { ELEMENT e ;

① NODE * temp = s->top ; if ( STACK_IsEmpty(s) ) {

……

}

② e= temp->item ;

③ s->top = temp->next ;

④ free(temp) ;

⑤ return e;

}

연결리스트로 구현된 스택

21

x top

m s

length u

temp ① e x ②

(22)

© 2011, J.-H.Kang, CNU

 노드가 하나인 리스트에서의 삭제는?

앞서의 코드는 노드가 하나만 있는 경우에도 정상 적으로 작동하는가?

연결리스트로 구현된 스택

22

x top

s

length

(23)

© 2011, J.-H.Kang, CNU

연결리스트로 구현된 스택

23

요 약

(24)

© 2011, J.-H.Kang, CNU

 요약

연결 리스트

 사용권 (pointer, address, reference)

 삽입과 삭제

 배열과의 차이점, 장단점

연결리스트로 구현핚 스택

 공개함수는 변하지 않는다.

 크기의 제핚을 받지 않는다.

연결리스트로 구현된 스택

24

(25)

© 2011, J.-H.Kang, CNU 25

실 습

연결 리스트 (Linked List)

수식 계산

(26)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

26

문제 설명

(27)

© 2011, J.-H.Kang, CNU

 개요

문제 자체는 [제10주 실습] 프로그램과 동일

 사용자의 관점에서 완전 동일

 즉, 동일핚 목적을 달성해야 함

Postfix 수식을 입력 받아 계산 결과를 출력핚다.

[제10주 실습]에서와 동일하게 오류 처리를 핚다.

차이점은?

 스택의 구현만 다르다.

 스택의 구현을 제외핚 다른 모든 코드는 전혀 변경 없이 재활용핚다.

[실습] 수식 계산

27

(28)

© 2011, J.-H.Kang, CNU

 문제

입출력

 입력:

매번 postfix 수식의 문자열을 scanf()로 읽어 들인다.

문자열의 첫 문자가 „$‟이면 프로그램을 종료핚다.

 출력:

읽어 들인 postfix 수식을 계산하여 결과를 출력핚다.

[실습] 수식 계산

28

(29)

© 2011, J.-H.Kang, CNU

 입력되는 postfix 수식의 형식

토큰(token)의 표현

 문자 하나가 하나의 토큰

„0‟~ „9‟: 연산 값 (수식의 숫자는 1자리 정수만 허락하기로 함)

„+‟, „-‟, „*‟, „/‟, „%‟: 연산자 (C 언어와 동일핚 의미)

„\0‟: 문자열의 끝

수식의 표현

 토큰의 나열

예: 8 7 5 - / 9 4 - 1 2 + - *

[실습] 수식 계산

29

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]

8 7 5 - / 9 4 - 1 2 + - * \0

(30)

© 2011, J.-H.Kang, CNU

 출력의 예

[실습] 수식 계산

30

<Postfix 수식을 계산합니다>

> Postfix 수식을 입력하시오: 38- 3 : STACK <Bottom> 3 <Top>

8 : STACK <Bottom> 3 8 <Top>

- : STACK <Bottom> -5 <Top>

계산값 : -5

> Postfix 수식을 입력하시오: 57*8%

5 : STACK <Bottom> 5 <Top>

7 : STACK <Bottom> 5 7 <Top>

* : STACK <Bottom> 35 <Top>

8 : STACK <Bottom> 35 8 <Top>

% : STACK <Bottom> 3 <Top>

계산값 : 3

> Postfix 수식을 입력하시오: 875-/94-12+-*

8 : STACK <Bottom> 8 <Top>

7 : STACK <Bottom> 8 7 <Top>

5 : STACK <Bottom> 8 7 5 <Top>

- : STACK <Bottom> 8 2 <Top>

/ : STACK <Bottom> 4 <Top>

9 : STACK <Bottom> 4 9 <Top>

4 : STACK <Bottom> 4 9 4 <Top>

- : STACK <Bottom> 4 5 <Top>

1 : STACK <Bottom> 4 5 1 <Top>

2 : STACK <Bottom> 4 5 1 2 <Top>

+ : STACK <Bottom> 4 5 3 <Top>

- : STACK <Bottom> 4 2 <Top>

* : STACK <Bottom> 8 <Top>

계산값 : 8

> Postfix 수식을 입력하시오: 82/3–42*+

8 : STACK <Bottom> 8 <Top>

2 : STACK <Bottom> 8 2 <Top>

/ : STACK <Bottom> 4 <Top>

3 : STACK <Bottom> 4 3 <Top>

– : STACK <Bottom> 1 <Top>

4 : STACK <Bottom> 1 4 <Top>

2 : STACK <Bottom> 1 4 2 <Top>

* : STACK <Bottom> 1 8 <Top>

+ : STACK <Bottom> 9 <Top>

계산값 : 9

> Postfix 수식을 입력하시오: 97%78*-253/+*

9 : STACK <Bottom> 9 <Top>

7 : STACK <Bottom> 9 7 <Top>

% : STACK <Bottom> 2 <Top>

7 : STACK <Bottom> 2 7 <Top>

8 : STACK <Bottom> 2 7 8 <Top>

* : STACK <Bottom> 2 56 <Top>

- : STACK <Bottom> -54 <Top>

2 : STACK <Bottom> -54 2 <Top>

5 : STACK <Bottom> -54 6 5 <Top>

3 : STACK <Bottom> -54 6 5 3 <Top>

/ : STACK <Bottom> -54 6 1 <Top>

+ : STACK <Bottom> -54 7 <Top>

* : STACK <Bottom> -378 <Top>

계산값 : -378

> Postfix 수식을 입력하시오: $

<계산을 종료합니다>

(31)

© 2011, J.-H.Kang, CNU

 오류처리를 위한 보완

[제10주 실습]의 문제점을 파악하고 보완핚다.

 기본 내용은 동일

무엇이 문제인가?

 수식에 오류가 있다면?

 문자열의 길이가 스택의 용량을 넘으면?

[실습] 수식 계산

31

(32)

© 2011, J.-H.Kang, CNU

 오류를 포함한 출력의 예 (스택 크기 5)

[실습] 수식 계산

32

<Postfix 수식을 계산합니다>

> Postfix 수식을 입력하시오: 38-- 3 : STACK <Bottom> 3 <Top>

8 : STACK <Bottom> 3 8 <Top>

- : STACK <Bottom> -5 <Top>

-: STACK <Bottom> <Top>

[오류] 연산값에 비해 연산자의 수가 많습니다.

> Postfix 수식을 입력하시오: 57*8%9 5 : STACK <Bottom> 5 <Top>

7 : STACK <Bottom> 5 7 <Top>

* : STACK <Bottom> 35 <Top>

8 : STACK <Bottom> 35 8 <Top>

% : STACK <Bottom> 3 <Top>

9 : STACK <Bottom> 3 9 <Top>

[오류] 연산값에 비해 연산자의 수가 적습니다.

> Postfix 수식을 입력하시오: 123456+++++

1 : STACK <Bottom> 1 <Top>

2 : STACK <Bottom> 1 2 <Top>

3 : STACK <Bottom> 1 2 3 <Top>

4 : STACK <Bottom> 1 2 3 4 <Top>

5 : STACK <Bottom> 1 2 3 4 5 <Top>

6 : STACK <Bottom> 1 2 3 4 5 <Top>

[오류] 수식이 너무 길어 처리가 불가능합니다.

> Postfix 수식을 입력하시오: 82^

8 : STACK <Bottom> 8 <Top>

2 : STACK <Bottom> 8 2 <Top>

^ : STACK <Bottom> 8 2 <Top>

[오류] 수식에 알 수 없는 연산자가 있습니다.

> Postfix 수식을 입력하시오: 97%78*-253/+*

9 : STACK <Bottom> 9 <Top>

7 : STACK <Bottom> 9 7 <Top>

% : STACK <Bottom> 2 <Top>

7 : STACK <Bottom> 2 7 <Top>

8 : STACK <Bottom> 2 7 8 <Top>

* : STACK <Bottom> 2 56 <Top>

- : STACK <Bottom> -54 <Top>

2 : STACK <Bottom> -54 2 <Top>

5 : STACK <Bottom> -54 6 5 <Top>

3 : STACK <Bottom> -54 6 5 3 <Top>

/ : STACK <Bottom> -54 6 1 <Top>

+ : STACK <Bottom> -54 7 <Top>

* : STACK <Bottom> -378 <Top>

계산값 : -378

> Postfix 수식을 입력하시오: $

<계산을 종료합니다>

(33)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

33

[실습 07-1]

main()의 구성

(34)

© 2011, J.-H.Kang, CNU

 Postfix 계산의 추상화

 main()의 관점에서는 postfix 계산에 대해서 자세히 알고 싶지 않다.

 단지 postfix 수식을 Postfix 객체에 넘겨주면, 그 Postfix 객체로부터 계 산 결과만 얻고 싶을 뿐이다.

 Postfix 계산을 Class로 !

[실습] 수식 계산

34

postfix

Postfix_setExpression() Postfix_eval ()

Postfix_computedValue() main()

inputPostfix()

“35+”

수식 전달

계산 지시

계산 값 얻어옴

(35)

© 2011, J.-H.Kang, CNU

 main()의 구성

#define MAXNUMEBROFTOKENS 200

#define MSG_StartingMessage “<Postfix 수식을 계산합니다>\n”

#define MSG_EndingMessage “\n<계산을 종료합니다>\n”

void main(void)

{ char expression[MAXNUMEBROFTOKENS] ; Postfix * postfix ;

boolean isInputEnded ; ; int returnCode ;

printMessage(MSG_StartingMessage) ; postfix = Postfix_new() ;

isInputEnded = inputPostfix(expression) ; while ( ! isInputEnded ) {

Postfix_setExpression(postfix, expression) ; returnCode = Postfix_eval(postfix) ;

if ( returnCode == ERROR_NONE ) {

printf(“계산값 : %d\n”, Postfix_computedValue(postfix)) ; } else {

outputErrorMessage(returnCode) ; } isInputEnded = inputPostfix(expression) ; } Postfix_free(postfix) ;

printMessage(MSG_EndingMessage) ; }

[실습] 수식 계산

35

(36)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

36

Class “Postfix” 의 공개함수

- [제10주 실습]의 것을 그대로 -

(37)

© 2011, J.-H.Kang, CNU

 Postfix의 공개함수

 Postfix * Postfix_new ()

 void Postfix_free (Postfix * postfix)

 void Postfix_setExpression (Postfix * postfix, char expression[])

 계산핛 수식 expression을 postfix 객체에 전달핚다.

 int Postfix_eval (Postfix * postfix)

 현재 객체가 가지고 있는 수식을 계산하도록 지시핚다.

 처리된 상태의 오류코드를 return 값으로 받는다.

 int Postfix_computedValue (Postfix * postfix)

 계산된 결과 값을 객체로부터 얻는다.

[실습] 수식 계산

37

(38)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

38

구현자적 관점에서의 Class “Postfix”의 구현

- [제10주 실습]의 것을 그대로 -

(39)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

39

Class “STACK” 의 공개함수

- 강의 자료를 볼 것 -

(40)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

40

구현자적 관점에서의 Class “STACK”의 구현

- Linked List로 -

- 강의 자료를 볼 것 -

(41)

© 2011, J.-H.Kang, CNU

[실습] 수식 계산

41

요 약

(42)

© 2011, J.-H.Kang, CNU

 생각해 볼 점

 스택의 구현이 바뀌었다!

 다른 프로그램 코드는 전혀 바뀌지 않고 완성되었는가?

 코드의 재활용과 공개함수의 관계는?

 공개함수는 구현을 감추고 있다고 생각되는가?

 라이브러리는 어떻게 여러 사람이 아무 문제 없이 잘 사용하고 있는가?

 요즈음의 소프트웨어는 매우 크다. 이미 개발되어 있는 라이브 러리를 많이 사용하고 있다.

 라이브러리의 구현자는 라이브러리의 내용을 아무 때나 마음대 로 바꿀 수 있는가?

 라이브러리 함수의 call 방법을 구현자가 마음대로 바꾸었다면 어떤 일이 벌어질까?

[실습] 수식 계산

42

(43)

© 2011, J.-H.Kang, CNU 43

[제 12 주] 끝

연결 리스트로 구현된 스택

(44)

© 2011, J.-H.Kang, CNU

© 2011, J.-H.Kang 44

참조

관련 문서

최근에 많이 사용되고 있는 볼라드는 강관이나, 스테인레스 강관을 주로 사용하고 있으며, 강관의 표면에 폴리우레탄 등의 소재를 강관표면에 부착 하여 충격을 완화하는

첫째, 현재 마을공동체 활성화를 위해 정부 주도하에 도시재생지원사업이 실시되고 있으며 온라인 플랫폼은 해당 지자체의 도시재생지원센터 홈페이지 위주로

외국에선 OSMU 보다 COPE(create once publish everywhere) 란 용어를 많이 사용하고 있다.. 2) 윈도우

이러한 기판 분리 공정을 포함하는 경우 인듐 뿐만 아니라 유리 기판의 재활용율 역시 높아질 가 능성이 있는 반면 , 대량으로 발생되는 사용 후 제품 들에 대한

세 번째 문제는 선정된 어휘를 기존의 사전(한글학회 우리말 큰사전)을 이용하여 다의어를 구분하고 각 의미에 가장 적절한 개념체계를 가능한 자동적으로 부여하

최신 의료기술의 발달과 더불어 진단영역에서도 다중 검출기 전산화단층촬영 장치가 개발되어 각종 의료기관에 서 많이 이용되고 있지만 환자에게는 상대적으로 많은

이러한 배경에서 이 연구는 사회복지 재정지출의 긍정적 영향과 부정적 영향 에 대한 논의를 정확히 이해하고, 이를 통해 서울시 복지지출의 향후 방향에 대한 시사점을

임상에서 가장 많이 활용하는 침법으로는 체침법을 기본으로 사암침법과 동씨침법을 가장 많이 활용한다고 나타났지만(표 3. 이는 임상에서 여러 가지 침법을 활용하여