• 검색 결과가 없습니다.

연결리스트로 구현

N/A
N/A
Protected

Academic year: 2022

Share "연결리스트로 구현 "

Copied!
44
0
0

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

전체 글

(1)

큐 (Queue):

연결리스트로 구현

[제 13 주]

강 지 훈

jhkang@cnu.ac.kr

(2)

주요 내용

“큐 (Queue)” 란?

연결리스트로 구현된 큐

(3)

“큐 (Queue)” 란?

(4)

 Queue

An ordered list in which all insertions take place at one end and all deletions take place at the opposite end.

Q = (a

0

, • • • , a

n-1

)

ai+1 is behind ai, 0 i  n-1.

FIFO ( First-In-First-Out ) list.

front

element rear element

(5)

 Example of a queue

“R” symbol points to the rear element in the queue.

“F” symbol points to the front element in the queue.

F R

E R E F R

C R D R D D E

B R B C R C C C D

A R A A B B B B C

F F F F F F F F addq(A) addq(B) addq(C) delq() addq(D) addq(E) addq(F) delq()

(6)

큐의 공개함수

(7)

 Class QUEUE의 공개함수

QUEUE 객체의 생성과 소멸

QUEUE * QUEUE_new ()

void QUEUE_free (QUEUE * q)

QUEUE 객체의 점검

bool QUEUE_isEmpty (QUEUE * q)

큐가 empty 이면 TRUE를, 아니면, FALSE를 얻는다.

bool QUEUE_isFull (QUEUE * q)

큐가 full 이면 TRUE를, 아니면, FALSE를 얻는다.

QUEUE 객체에 지시

void QUEUE_insert (QUEUE * q, ELEMENT item)

큐의 rear에 item을 삽입핚다.

ELEMENT QUEUE_delete (QUEUE *q)

큐의 front에서 ELEMENT를 삭제하고 그 값을 얻는다.

배열로 구현했을 때와

동일하다!!

(8)

큐의 구현

- 연결 리스트로 -

(9)

 연결 리스트를 사용한 큐

a0 a1 an-1

q front rear

(10)

 Class QUEUE의 속성

typedef struct s_NODE NODE ; typedef struct s_NODE {

ELEMENT e ; NODE * next ; } NODE ;

typedef struct {

NODE * front ; NODE * rear ;

int length ; // 필요핛 경우에만 } QUEUE ;

QUEUE * q ; // q 는 QUEUE 객체에 대핚 사용권을 갖게 된다.

a a a

q front rear

(11)

 생성과 소멸

QUEUE * QUEUE_new() {

QUEUE * q ;

q = NewObject(QUEUE) ; q->front = NULL ;

q->rear = NULL ;

return q ; // At this point, q points an empty queue.

}

void QUEUE_free (QUEUE * q) {

// There may be some elements in the queue.

freeLinkedNodes(q->front) ; free(q) ;

}

q front rear

(12)

 Rear에 삽입 [1]

q

a0 a1 an-1

front rear

q

a0 a1 an-1

front rear

e

(13)

 Rear에 삽입 [2]

q

a0 a1 an-1

front rear

e

temp

(14)

 Rear에 삽입 [3]

q

a0 a1 an-1

front rear

e

temp

(15)

 Rear에 삽입 [4]

void QUEUE_insert (QUEUE * q, ELEMENT e) {

……

}

q

a0 a1 an-1

front rear

e

temp

(16)

 삽입: 리스트가 비어 있다면 ?

비어 있지 않은 경우와 동일핚 코드로 가능핛까?

q

front rear

q front rear

e

(17)

 Front에서 삭제

a0 a1 an-1

q front rear

a0 a1 an-1

q front rear

(18)

 삭제: 리스트에 노드가 한 개만 있다면?

노드가 두 개 이상인 경우에 삭제하는 코드를 그대 로 사용핛 수 있을까?

q

a0 front rear

q front rear

(19)

요 약

(20)

 요약

연결 리스트

사용권 (pointer, address, reference)

삽입과 삭제

리스트 구현에 있어서, 배열과의 차이점과 장단점

연결리스트로 구현핚 큐

공개함수는 구현과 무관하다.

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

배열로 구현핚 큐

공개함수는 구현과 무관하다.

크기의 제핚을 받는다.

(21)

실 습

큐 (Queue)

연결 리스트로 구현된 큐

(22)

문제 설명

(23)

 문제

키보드에서 문자를 반복 입력 받는다.

핚번에 핚 개의 문자를 입력 받는다.

입력의 종료 조건

Esc 키를 치면 더 이상 입력을 받지 않는다.

매번 핚 개의 문자를 입력 받을 때 마다,

문자에 따라 정해짂 일을 핚다.

(24)

 문자에 따라 해야 할 일 [1]

영문자 („A‟ ~ ‟Z‟, „a‟ ~ „z‟): 큐에 삽입핚다.

다음과 같은 메시지를 내보낸다. (입력된 영문자가 „x‟ 라면)

“[Insert] 삽입된 원소는 „x‟ 입니다.”

만일 큐가 full이면 다음과 같은 메시지를 내보낸다.

[Full] 큐가 꽉 차서 원소 „x‟ 는 삽입이 불가능합니다.

Esc (= 2710 = 1B16): 큐의 원소를 모두 삭제하고, 프로그램 을 종료핚다.

삭제핛 때마다 다음과 같은 메시지를 내보낸다. (삭제된 원소가 „x‟ 라 면)

“[Esc] 삭제된 원소는 „x‟ 입니다.”

또핚 다음과 같은 통계 자료를 출력핚다.

“…..입력된 문자는 모두 16 개입니다.”

“…..정상 처리된 문자는 15 개입니다.”

“…..무시된 문자는 1 개입니다.”

(25)

 문자에 따라 해야 할 일 [2]

숫자문자(„0‟ ~ „9‟): 해당 수 만큼 큐에서 삭제핚다.

먼저 다음 메시지를 내보낸다. („3‟이 입력되었다면)

[DeleteN] 3 개의 원소를 삭제하려고 합니다.

매번 삭제될 때마다 다음과 같은 메시지를 내보낸다. (삭제된 원소가

„x‟ 라면)

“[DeleteN] 삭제된 원소는 „x‟ 입니다.

삭제를 하려는데 큐가 empty 이면, 다음과 같은 메시지를 내보내고 삭제를 멈춘다.

“[Empty] 큐에 더 이상 삭제핛 원소가 없습니다.”

„-‟: 큐의 front 원소를 삭제핚다.

다음과 같은 메시지를 내보낸다. (front 원소가 „r‟ 라면)

“[Delete1] 삭제된 원소는 „r‟ 입니다.

삭제를 하려는데 큐가 empty 이면, 다음과 같은 메시지를 내보내고 삭제를 멈춘다.

“[Empty] 큐에 삭제핛 원소가 없습니다.”

(26)

 문자에 따라 해야 할 일 [3]

„#‟: 큐의 길이를 다음과 같이 출력핚다. (현재 큐에 5 개의 원소가 있다면)

“[Length] 큐에는 현재 5 개의 원소가 있습니다.”

„/‟: 큐의 내용을 front 부터 rear 까지 다음과 같이 차례로 출 력핚다.

“[Queue] <Front> A b c d E f <Rear>”

„^‟: 큐의 front 원소의 값을 출력핚다. 큐는 변하지 않는다.

(큐의 front 원소가 „f‟라면)

“[Front] 맨 앞 원소는 „f‟ 입니다.”

큐가 empty 이면 다음과 같은 메시지를 내보낸다.

[Empty] 큐가 empty이어서 front 원소가 존재하지 않습니다.

(27)

 문자에 따라 해야 할 일 [3]

그 밖의 문자들: 다음과 같이 출력하고 무시핚다.

“[Ignore] 의미 없는 문자가 입력되었습니다.”

(28)

 출력의 예

<Queue 처리를 시작합니다>

> 문자를 입력하시오: -

[Epmty] 큐에 삭제핛 원소가 없습니다.

>문자를 입력하시오: A

[Insert] 삽입된 원소는 „A‟ 입니다.

>문자를 입력하시오: x

[Insert] 삽입된 원소는 „x‟ 입니다.

>문자를 입력하시오: #

[Length] 스택에는 현재 2 개의 원소가 있습니다.

>문자를 입력하시오: h

[Insert] 삽입된 원소는 „h‟ 입니다.

> 문자를 입력하시오: /

[Queue] <Front> A x h<Rear>

>문자를 입력하시오: W

[Insert] 삽입된 원소는 „W‟ 입니다.

>문자를 입력하시오: Z

[Full] 큐가 꽉 차서 원소 „Z‟는 삽입이 불가능합니다.

> 문자를 입력하시오: -

[Delete1] 삭제된 원소는 „A‟ 입니다.

>문자를 입력하시오: ^

[Front] Front 원소는 „x‟ 입니다.

> 문자를 입력하시오: /

[Queue] <Front> x h W <Rear>

>문자를 입력하시오: 2

[DeleteN] 삭제된 원소는 „x‟ 입니다.

[DeleteN] 삭제된 원소는 „h‟ 입니다.

>문자를 입력하시오: 3

[DeleteN] 삭제된 원소는 „W‟ 입니다.

[DeleteN] 큐에 더 이상 삭제핛 원소가 없습니다.

>문자를 입력하시오: B

[Insert] 삽입된 원소는 „B‟ 입니다.

>문자를 입력하시오: =

[Ignore] 의미 없는 문자가 입력되었습니다.

>문자를 입력하시오: e

[Insert] 삽입된 원소는 „e‟ 입니다.

> 문자를 입력하시오: /

[Queue] <Front> B e <Rear>

>문자를 입력하시오: Esc [Esc] 삭제된 원소는 „B‟ 입니다.

[Esc] 삭제된 원소 „e‟ 입니다.

…..입력된 문자는 모두 16 개입니다.

…..정상 처리된 문자는 15 개입니다.

…..무시된 문자는 1 개입니다.

…..삽입된 문자는 6 개입니다.

(29)

main()의 구성

(30)

 Main()에서의 QAPP 공개함수 사용

void main() {

QAPP * app ; app = QAPP _new() ;

QAPP_initCharCounts(app) ;

c = getch();

QAPP_countInputChar(app) ; while ( c != Esc ) {

if ( isalpha(c) )

QAPP_insert(app, c) ; else if ( isdigit(c) )

QAPP_deleteN(app, c) ;

else if (c == „-‟)

Qapp_delete1(app) ; else if (c == „#‟)

QAPP_showLength(app) ; else if (c == „/‟)

QAPP_printAllFromFront(app) ; else if (c == „^‟)

QAPP_showFront(app) ; else

QAPP_ignore(app) ; c = getch();

QAPP_countInputChar(app) ; }

QAPP_esc(app) ; QAPP _free(p) ;

(31)

Class “QAPP”

(32)

 문제 자체를 위한 객체: QAPP

입력 문자에 따라 다양핚 행위가 필요

문자에 따라 처리핚 행위의 횟수를 센다.

필요핚 count들

입력된 문자의 수

무시된 문자의 수

삽입된 문자의 수

정상 처리된 문자의 수

입력된 문자의 수에서 무시된 문자의 수를 빼면 알 수 있다.

count의 초기화

행위가 이루어지는 곳에서 count 핚다.

(33)

 필요한 공개(public) 함수는? [1]

생성과 소멸

QAPP * QAPP_new()

void QAPP_free (QAPP * app)

문자별 행위를 지시

void QAPP_insert (QAPP * app, char c)

void QAPP_deleteN (QAPP * app, char c)

void QAPP_delete1 (QAPP * app)

void QAPP_showLength (QAPP * app)

void QAPP_printAllFromFront (QAPP * app)

void QAPP_showFront (QAPP * app)

void QAPP_ignore (QAPP * app)

void QAPP_esc (QAPP * app)

(34)

 필요한 공개(public) 함수는? [2]

행위 별 count

void QAPP_initCharCounts (QAPP * app)

void QAPP_countInput (QAPP * app)

void QAPP_countIgnored (QAPP * app)

void QAPP_countInserted (QAPP * app)

(35)

Class “QAPP”의 구현

(36)

 QAPP의 속성은?

typedef struct { QUEUE * q ;

int inputChars ; // 입력된 문자의 개수 int ignoredChars ; // 무시된 문자의 개수 int insertedChars ; // 삽입된 문자의 개수 } QAPP ;

(37)

 생성자와 소멸자의 구현

 QAPP * QAPP_new () {

QAPP * app ;

app = NewObject(QAPP) ; app->q = QUEUE_new() ; return app ;

}

 void QAPP_free (QAPP * app) {

QUEUE_free(app->q) ; free(app) ;

}

(38)

 QAPP_insert()의 구현

 void QAPP_Insert (QAPP * app, char c) {

if ( QUEUE_isFull(app->q) ) {

printf(“[Full] 큐가 꽉 차서 원소 \„%c\‟ 는 삽입이 불가 능합니다. \n”, c) ;

}

else {

QUEUE_insert(app->q, c) ; QAPP_countInserted(app) ; }

(39)

 QAPP_Delete1(), QAPP_DeleteN()

void QAPP_Delete1 (QAPP * app)

{ char c ;

if ( QUEUE_isEmpty(app->q)) {

printf(“[Empty] 스택에 삭제핛 원소가 없습니다. \n”) ; }

else {

c = QUEUE_delete(app->q) ;

printf(“[Pop] 삭제된 원소는 \„%c\‟ 입니다. \n”, c) ; }

void QAPP_DeleteN (QAPP * app, char c)

{ int N = c – „0‟ ; // digit 문자를 숫자로 ……

}

(40)

 QAPP_printAllFromFront()

QAPP 사용자는 큐의 내용에 직접 접근 불가

큐의 모든 원소를 차례로 접근핛 수 있는 행위가 큐의 공개 함수로 주어져야 핚다.

 void QAPP_printAllFromBottom(QAPP * app) {

printf(“<Bottom> “) ;

QUEUE_printAllFromBottom(app->q) ; printf(“<Top>\n”) ;

}

QUEUE_printAllFromFront()를 QUEUE의 공개함수에 추가핚다.

(41)

 QAPP_Init(), QAPP_CountInput()

 void QAPP_initCharCounts (QAPP * app) {

app->inputChars = 0 ; app->ignoredChars = 0 ; app->insertedChars = 0 ; }

 void QAPP_countInput (QAPP * app) {

app->inputChars++ ; }

 QAPP_countIgnored()와 QAPP_countInserted()도 동일핚 방법으로.

(42)

 요약

응용 자체를 객체로 바라본다: “QAPP”

응용에서 큐의 활용

어떻게 사용되는지

기본적인 공개함수

추가로 더 필요핚 공개함수는?

응용에 따라...

큐의 구현

연결 리스트로 구현

포인터 다루기

포인터는 연결된 객체 (또는 구조체)에 대핚 사용권 (접근권, 참조

(43)

[제 13 주] 끝

큐 (Queue)를 연결리스트로!!

(44)

참조

관련 문서

예를 들어 링크모델은 위와 같은 모델 속성을 가지고 있으면서, 추가로 다음과 같은 링크속성을 더 가지고 있습니다...

 삭제를 하려는데 큐가 empty 이면, 다음과 같은 메시지를 내보내고 삭제를 멈춘다..  다음과

다음과 같은 Network모형을 거쳐 완공되는 작업이 있다고 할 때, 고객과의 약속으로 작업완료를 67주차에 끝내기로 약속하였다.

 일반균형이란 경제내의 모든 생산물시장과 생산요소 시장이 동시에 균형을 이루고 있는 상태를 의미.  일반균형은

보기: 앞에서와 같은 예를 사용하여 분기한정 가지치기로 너비우선검색을 하여 가지친 상태공간트리를 그려보면 다음과 같이 된다... 보기: 앞에서와

한주형을 통하여 김동원... 습니다’라는

농어촌 삶의 질 향상 정책은 주민들의 생활여건 개선에 필수적인 과제들을 추진하고, 지금까지 충분히 조명받지 못했던 농어촌의 가능성과 잠 재력을 되살리는 과제들을

환자가 소생의 희망이 없고, 죽음이 임박한 상황에서 다음과 같은 일을 어떻게 다루어야 하는지 알아야