chapter 10. 구조체와 리스트 처리 10.1 자기참조 구조체

43
1 Chapter 10. 구구구구 구구구 구구 10.1 구구구구 구구구 - 구구 구구구 구구 구구 구구구구 구구구구구 구구구 구구 구구구 구구 구구구 - 구구 구구구구 (dynamic data strutures) (구) struct list { int data; struct list *next; } a; next : NULL 구구 구구 list 구구구 구구구 구구구 구구 . NULL 구 list 구 구 . a data next → link( 구구 )

Upload: shina

Post on 22-Jan-2016

101 views

Category:

Documents


0 download

DESCRIPTION

a. data next → link( 연결 ). ↑. Chapter 10. 구조체와 리스트 처리 10.1 자기참조 구조체 - 자기 자신과 같은 형의 구조체를 포인트하는 포인터 멤버 필드를 갖는 구조체 - 동적 자료구조 (dynamic data strutures) ( 예 ) struct list { int data; struct list *next; } a; next : NULL 또는 다음 list 원소의 메모리 주소를 가짐 .NULL 은 list 의 끝. a. b. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

1

Chapter 10. 구조체와 리스트 처리

10.1 자기참조 구조체

- 자기 자신과 같은 형의 구조체를 포인트하는 포인터 멤버 필드를 갖는 구조체 - 동적 자료구조 (dynamic data strutures)

( 예 )struct list { int data; struct list *next;} a;

next : NULL 또는 다음 list 원소의 메모리 주소를 가짐 .NULL 은 list 의 끝 .

a

↑datanext → link( 연결 )

Page 2: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

2

- node 의 작성

struct list a, b, c;

a.data = 1;

b.data = 2;

c.data = 3;

a.next = b.next = c.next = NULL;

↑ NULL

1a

↑ NULL

2b

↑ NULL

3c

Page 3: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

3

- node 의 연결

a.next = &b;

b.next = &c;

- 연결된 원소의 자료 검색

a.next -> data : 2 (b.data)

b.next -> data : 3 (c.data)

a.next -> next -> data : 3 (c.data)

1a

2b

3c

Page 4: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

4

10.2 선형 연결 리스트 (Linear linked-lists)

- 구조체 자료들이 순차적으로 연결됨 .

1

2

3

↑head

Page 5: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

5

( 예 ) "list.h"

#include <stdio.h>#include <stdlib.h>

typedef char DATA;

struct linked_list {

DATA d;

struct linked_list *next;

} ;

typedef struct linked_list ELEMENT;

typedef ELEMENT *LINK;

- 위의 명세들 (typedef) 은 기억장소를 할당받지 않음 .

변수가 선언될 경우에만 기억장소를 할당함 .

Page 6: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

6

- 기억장소의 동적할당

( 예 )

LINK head;

head = malloc(sizeof(ELEMENT));

• ELEMENT type 의 기억장소가 동적으로 할당된 후 그 주소가 head 에 저장됨 .

- linear linked - list 의 작성 예

• 'n', 'e', 'w' 를 저장하는 linear linked-list

head = malloc(sizeof(ELEMENT));

head

↑ ↑

Page 7: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

7

head -> d = 'n';

head -> next = NULL;

head -> next = malloc(sizeof(ELEMENT));

head -> next -> d = 'e';

head -> next -> next = NULL;

head

↑ n ↑

head

↑ n ↑═

head

↑ n ↑ e ↑═

Page 8: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

8

head -> next -> next = malloc(sizeof(ELEMENT));

head -> next -> next -> d = 'w';

head -> next -> next -> next = NULL;

head

↑ n ↑ e ↑ w ↑═

Page 9: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

9

10.3 리스트 연산

- 기본연산• 리스트 생성• 원소 개수 세기• 원소 탐색• 두 리스트의 결합• 원소 삽입• 원소 삭제

Page 10: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

10

( 예 ) 문자열의 list 변환 - recursion(list 는 재귀적으로 정의됨 .)

#include "list.h"

LINK string_to_list(char s[]){ LINK head;

if (s[0] == '\0') return NULL;

else { head = malloc(sizeof(ELEMENT));

head -> d = s[0];

head -> next = string_to_list(s + 1);

return head; }}

Page 11: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

11

문자열 : s

A : call w/ s

B : call w/ s+1

C : call w/ s+2

a b c \0

a b c \0

head

↑ a ↑ ?

head

↑ b ↑ ?

head

↑ c ↑ ?

b c \0

c \0

Page 12: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

12

D : call w/ s+3

return NULL;

C' :

B' :

A' :

head

↑ c ↑

\0

═head

↑ b ↑ c ↑ ═

head

↑ a ↑ b ↑ c ↑ ═

Page 13: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

13

- ( 예 ) 문자열의 list 변환 : repetition( 반복 )

#include "list.h"

LINK s_to_l(char s[]){ LINK head = NULL, tail; int i;

if (s[0] != '\0') { head = malloc(sizeof(ELEMENT)); /* 1st element */ head -> d = s[0]; tail = head;

for (i = 1; s[i] != '\0'; ++i) { tail -> next = malloc(sizeof(ELEMENT)); tail = tail -> next; tail -> d = s[i]; } tail -> next = NULL; } return head; }

Page 14: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

14

• list w/ one element

• 두번째 element 첨부

• tail 의 갱신

head

tail

a ↑ ?

head

tail

a ↑ ? ↑ ?

head

tail

a ↑ b ↑ ?

Page 15: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

15

• 세번째 element 첨부

• tail 의 갱신

• '\0' 를 발견

head

tail

a ↑ b ↑ ? ↑ ?

head

tail

a ↑ b ↑ c ↑ ?

head

tail

a ↑ b ↑ c ↑

Page 16: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

16

10.4 리스트 처리 함수

- 리스트의 원소의 수를 세는 함수

• 재귀 version

int count(LINK head)

{

if (head == NULL)

return 0; else

return (1 + count(head -> next));

}

Page 17: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

17

• for loop 사용

int count(LINK head)

{

int cnt = 0;

for ( ; head != NULL; head = head -> next)

++ cnt;

return cnt;

}

Page 18: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

18

- 리스트의 원소를 출력

• 재귀 version

void print_list(LINK head)

{

if (head == NULL)

printf("\nNULL");

else {

printf("\n%c --> ", head -> d);

print_list(head -> next);

}

}

Page 19: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

19

- 문자열 "abc" 를 list 로 바꾸고 그 list 를 출력

#include "list.h"

LINK string_to_list(char []);void print_list(LINK);void count(LINK);

void main(){ LINK h;

h = string_to_list("abc");

printf("The resulting list is \n");

print_list(h);

printf("\nNumber of elements : %d", count(h));}

( 실행결과 )The resulting list isa --> b --> c --> NULLNumber of elements : 3

Page 20: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

20

- 두 list 의 결합

void concatenate(LINK a, LINK b)

{

assert(a != NULL);

if (a -> next == NULL)

a -> next = b;

else

concatenate(a -> next, b);

}

Page 21: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

21

- 새로운 원소의 삽입 : 고정된 시간 안에 삽입가능 .

(c.f. array : 배열의 길이에 비례 )

• 삽입전

void insert(LINK p1, LINK p2, LINK q){ assert(p1 -> next == p2);

p1 -> next = q;

q -> next = p2;}

P1P2

...q

A ↑ C ↑

B ↑

...

Page 22: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

22

• 삽입 후P1

P2

...q

A ↑ C ↑

B ↑

...

Page 23: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

23

- 원소의 삭제• 삭제 전

/* temp = p -> next; */

p -> next = p -> next -> next;

/* free(temp); */

• 삭제 후

P

...A ↑ C ↑B ↑ ...

P

...A ↑ C ↑B ↑ ...

temp

Page 24: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

24

- 리스트의 삭제 : 재귀호출

void delete_list(LINK head){

if (head != NULL) {

delete_list(head -> next); free(head);

}}

Page 25: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

25

10.5 stacks

- 구현

cnt↑ top

stack

data

elem

data

data

↑NULL

• •

Page 26: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

26

- "stack.h"

#include <stdio.h>

#include <stdlib.h>

#define EMPTY 0#define FULL 10000

typedef char data;typedef enum {false, true} boolean;

struct elem {

data d; struct elem *next;

};

typedef struct elem elem;

Page 27: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

27

struct stack {

int cnt; elem *top;

};

typedef struct stack stack;

void initialize(stack *stk);void push(data d, stack *stk);data pop(stack *stk);data top(stack *stk);boolean empty(const stack &stk);boolean full(const stack &stk);

Page 28: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

28

- ADT stack(linked - list version)

#include "stack.h"

void initialize(stack *stk){ stk -> cnt = 0; stk -> top = NULL;}

void push(data d, stack *stk){ elem *p; p = malloc(sizeof(elem)); p -> d = d; p -> next = stk -> top; stk -> top = p; stk -> cnt++;}

Page 29: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

29

data pop(stack *stk){

data d; elem *p;

d = stk -> top -> d; p = stk -> top; stk -> top = stk -> top -> next; stk -> cnt--;

free(p);

return d;

}

Page 30: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

30

data top(stack *stk){ return (stk -> top -> d);}

boolean empty(const stack *stk){ return ( (boolean)(stk -> cnt == EMPTY));}

boolean full(const stack stk){ return ( (boolean)(stk -> cnt == FULL));}

Page 31: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

31

( 예 ) reverse stringint main(){ chat str[] = "Mary had a little lamb"; int i; stack s;

initialize(&s); printf("In the string : %s\n", str);

for (i = 0; str[i] != '\0'; ++i) if (!full(&s)) push(str[i], &s);

printf("From the stack : ");

while(!empty(&s)) putchar(pop(&s));

putchar('\n'); return 0;}

( 실행결과 )In the string : Mary had a little lamb.From the stack : .bmal ettil a dah yraM

Page 32: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

32

< 비교 > ADT stack(array 의 사용 예 )#include <stdio.h>void main(){ char str[] = "Mary had a little lamb."; int i; stack s; reset(&s); /* stack 의 초기화 */ printf("In the string : %s\n", str); for (i = 0; str[i] != '\0'; ++i) if (!full(&s)) push(str[i], &s); printf("From the stack"); while(!empty(&s)) putchar(pop(&s)); putchar('\n');}

( 실행결과 )In the string : Mary had a little lamb.From the stack : .bmal ettil a dah yraM

Page 33: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

33

10.6 Polish Notation

10.7 Queue

- 선형 연결 리스트를 이용

- FIFO(First-In-First-Out)

- 구현

count

front

rear

queue

data

↑ data

↑ data

elem

삽입 : list 의 rear 에 삽입됨 .삭제 : list 의 front 에서 삭제됨 .

Page 34: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

34

- "queue.h"

#include <assert.h>

#include <stdio.h>

#include <stdlib.h>

#define EMPTY 0

#define FULL 10000

typedef unsigned int data;

typedef enum {false, true} boolean;

struct elem {

data d; struct elem *next;

};

Page 35: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

35

typedef struct elem elem;

struct queue {

int cnt; elem *front; elem *rear;

};

typedef struct queue queue;

void initialize(queue *q);void enqueue(data d, queue *q);data dequeue(queue *q);data front(const queue *q);boolean empty(const queue *q);boolean full(const queue *q);

Page 36: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

36

- "queue.c"

#include "queue.h"

void initialize(queue *q){

q -> cnt = 0; q -> front = NULL; q -> rear = NULL;

}

0

NULL

NULL

queue

Page 37: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

37

data dequeue(queue *q){

data d; elem *p;

d = q -> front -> d; p = q -> front; q -> front = q -> front -> next; q -> cnt--; free(p);

return (d);}

Page 38: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

38

n

front

rear

queue

54 ↑

(n - 1)

13

d p

13 ↑ 7 ↑•••

Page 39: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

39

void enqueue(data d, queue *q){ elem *p;

p = malloc(sizeof(elem)); p -> d = d; p -> next = NULL;

if(!empty(q)) { q -> rear -> next = p; q -> rear = p; } else q -> front = q -> rear = p;

q -> cnt ++;}

Page 40: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

40

n

front

rear

queue

250 ↑

(n + 1)

p d

5 ↑ 13 ↑

d NULL

•••

Page 41: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

41

data front(const queue *q){ return (q -> front -> d);}

boolean empty(const queue *q){ return ( (boolean)(q -> cnt == EMPTY));}

boolean full(const queue *q){ return ( (boolean)(q -> cnt == FULL));}

Page 42: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

42

숙제 .

1. 문자열을 입력하여 각 문자를 element 의 data 로 하는 linked-list 를 작성한 후 linked-list 의 모든 문자를 출력하는 program 을 작성하라 .

2. 위의 data 를 이용하여 문자열의 길이를 출력하는 program 을 작성하라 .

3. 한 문자를 입력 받아 그 문자가 위의 linked-list 에 있으면 그 element 를 list 에서 제외한 후 남은 문자열을 출력하고 ,

그 문자가 없으면 message 와 함께 문자열을 출력하는 program 을 작성하라 .

Page 43: Chapter 10.  구조체와 리스트 처리 10.1  자기참조 구조체

43

숙제 .

4. 10, 20, 30, 40, 50 으로 linked-list 를 만들고 0~60 사이의 정수를 입력하여 list 에 ascending order 를 지켜 추가한 후 list 의 모든 수를 출력하는 program 을 작성하라 . 단 , 입력은 여러번 주어진다 . ( 약 10 회 정도 )

5. 문자열을 입력하여 각 문자를 element 로 하는 stack 과 queue 를 작성한 후 's' 를 입력하면 순서대로 (queue 를 이용 ), 'r' 을 입력하면 역순으로 (stack 을 이용 ) 출력하는 program 을 작성하라 .(ADT 를 사용할 것 )