• 검색 결과가 없습니다.

06 리스트

N/A
N/A
Protected

Academic year: 2022

Share "06 리스트"

Copied!
31
0
0

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

전체 글

(1)

--- DATA

STRUCTURES USING C

---

리스트

06

CHAPTER

(2)

• 리스트(list), 선형리스트(linear list)

– 순서를 가진 항목들의 모임

– 집합: 항목간의 순서의 개념이 없음

• 리스트의 예

– 요일: (일요일, 월요일, …, 토요일) – 한글 자음의 모임: (ㄱ,ㄴ,…,ㅎ) – 카드: (Ace, 2,3,…,King)

– 핸드폰의 문자 메시지 리스트 – 다항식의 각 항들

리스트란?

(3)
(4)

• Stack, Queue, Deque과의 공통점과 차이점

– 선형 자료구조 – 자료의 접근 위치

리스트의 구조

(5)

• 기본 연산

– 리스트의 어떤 위치에 새로운 요소를 삽입한다.

– 리스트의 어떤 위치에 있는 요소를 삭제한다.

– 리스트의 어떤 위치에 있는 요소를 반환한다.

– 리스트가 비었는지를 살핀다.

– 리스트가 가득 차있는지를 체크한다.

• 고급 연산

– 리스트에 어떤 요소가 있는지를 살핀다.

– 리스트의 어떤 위치에 있는 요소를 새로운 요소로 대치한다.

– 리스트 안의 요소의 개수를 센다.

– 리스트 안의 모든 요소를 출력한다.

리스트의 연산

(6)

데이터: 임의의 접근 방법을 제공하는 같은 타입 요소들의 순서 있는 모임 연산:

▪ init(): 리스트를 초기화한다.

▪ insert(pos, item): pos 위치에 새로운 요소 item을 삽입한다.

▪ delete(pos): pos 위치에 있는 요소를 삭제한다.

▪ get_entry(pos): pos 위치에 있는 요소를 반환한다.

▪ is_empty(): 리스트가 비어있는지를 검사한다.

▪ is_full(): 리스트가 가득 차 있는지를 검사한다.

▪ find(item): 리스트에 요소 item이 있는지를 살핀다.

▪ replace(pos, item): pos 위치를 새로운 요소 item으로 바꾼다.

리스트 ADT

(7)

• 배열을 이용

– 구현이 간단

– 삽입, 삭제시 오버헤드 – 항목의 개수 제한

• 연결리스트를 이용

– 구현이 복잡

– 삽입, 삭제가 효율적 – 크기가 제한되지 않음

a b c

a b c NULL

a b c

배열을 이용한 구현

연결리스트를 이용한 구현 리스트 ADT

리스트 구현 방법

(8)

• 1차원 배열에 항목들을 순서대로 저장

– L=(A, B, C)

배열로 구현된 리스트

typedef int Element;

Element data[MAX_LIST_SIZE];

int length = 0;

(9)

• 공백상태 / 포화상태

공백상태 / 포화상태

length

[0] [1] [2] [3]

(a) 공 백 상 태

[MAX_LIST_SIZE-1]

length

[0]

A B C D F

[1] [2] [3]

(b) 포 화 상 태

[MAX_LIST_SIZE-1]

(10)

• 삽입위치 다음의 항목들을 이동하여야 함.

length

length A B C D E

A B N C D E

[ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]

[ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]

( a ) 삽 입 전

( b ) 삽 입 후 N

삽입 연산

void insert( int pos, Element e ) {

int i;

if(is_full()==0 && pos >= 0 && pos<=length){

for( i=length ; i>pos ; i-- ) data[i] = data[i-1];

data[pos] = e;

length++;

}

else error("포화상태 오류 또는 삽입 위치 오류");

}

(11)

• 삭제위치 다음의 항목들을 이동하여야 함

length

length

[ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]

[ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]

( a ) 삭 제 전

( b ) 삭 제 후 A B C D E

A B D E C

삭제 연산

void delete( int pos ) {

int i;

if( is_empty()==0 && 0<=pos && pos<length ) { for(i=pos+1 ; i<length ; i++ )

data[i-1] = data[i];

length--;

}

else error("공백상태 오류 또는 삭제 위치 오류");

}

(12)

전체 프로그램

void main() {

init_list();

insert(0, 10);

insert(0, 20);

insert(1, 30);

insert(size(), 40);

insert(2, 50);

print_list("배열로 구현한 List(삽입x5)");

replace(2, 90);

print_list("배열로 구현한 List(교체x1)");

delete(2);

delete(size() - 1);

delete(0);

print_list("배열로 구현한 List(삭제x3)");

(13)

• Lab

(14)

• 단순 연결 리스트(simple linked list) 사용

– 하나의 링크 필드를 이용하여 연결 – 마지막 노드의 링크 값은 NULL

연결 리스트로 구현한 리스트

(15)

데이터

• 구조체

• 데이터

typedef int Element;

typedef struct LinkedNode {

Element data;

// 데이터 필드

struct LinkedNode* link;

// 링크 필드

} Node;

Node* head;

// 헤드 포인터

(16)

단순한 연산들

C D NULL

A B

최 초 의 p는 헤 드 포 인 터 p

Node* p = head; 이 후 로 link를 따 라 진 행 p = p->link;

헤 드 포 인 터 head

int size() {

Node* p;

int count = 0;

for (p = head; p != NULL; p = p->link) count++;

return count;

}

Node* get_entry(int pos) {

Node* n = head;

int i;

for (i = 0; i<pos; i++, n = n->link) if (n == NULL) return NULL;

(17)

삽입연산

void insert_next(Node *prev, Node *n) {

if (n != NULL) {

n->link = prev->link;

prev->link = n;

} }

void insert(int pos, Element val) {

Node *new_node, *prev;

new_node = (Node*)malloc(sizeof(Node));

new_node->data = val;

new_node->link = NULL;

if (head == NULL) head = new_node;

else {

prev = get_entry(pos - 1);

if (prev != NULL)

insert_next(prev, new_node);

}

(a) 삽입하기 전 C

N B

before

node

(b) 삽입한 후 C

N B

(2) (1) before

node

(18)

( a ) 삭 제 하 기 전

( b ) 삭 제 한 후 N

B

before removed

C a f t e r

N B

before removed

C a f t e r (1)

삭제연산

Node* remove_next(Node *prev) {

Node* removed = prev->link;

if (removed != NULL)

prev->link = removed->link;

return removed;

}

void delete(int pos) {

Node* prev, *removed;

if (pos == 0 && is_empty() == 0) { removed = head;

head = head->link;

free(removed);

} else {

prev = get_entry(pos - 1);

if (prev != NULL) {

(19)

전체 프로그램

void main() {

init_list( );

insert( 0, 10 );

insert( 0, 20 );

insert( 1, 30 );

insert( size(), 40 );

insert( 2, 50 );

print_list("단순연결리스트로 구현한 List(삽입x5)");

replace(2, 90);

print_list("단순연결리스트로 구현한 List(교체x1)");

delete( 2 );

delete( size()-1);

delete( 0);

print_list("단순연결리스트로 구현한 List(삽입x3)");

clear_list( );

print_list("단순연결리스트로 구현한 List(정리후)");

}

(20)

헤드포인터와 헤드 노드

C D

NULL

A B

헤 드 포 인 터 (head)

(a) 헤 드 포 인 터 를 사 용 하 여 구 현 한 리 스 트

? A B C D

NULL

헤 드 노 드 (org)

실 제 헤 드 포 인 터 = org.link

(b) 헤 드 노 드 를 사 용 하 여 구 현 한 리 스 트

낭 비 되 는 데 이 터 필 드

Node org;

// 헤드 노드 org. 실제 헤드 포인터는 org.link가 됨

(21)

• Circular Linked List

• 변형된 원형 연결 리스트

헤 드 포 인 터

원형 연결 리스트

(22)

• 후속 노드는 쉽게 알 수 있다.(링크 필드)

• 선행 노드를 알 수는 없을까?

헤 드 포 인 터

NULL

나 의 선 행 노 드 는?

이중 연결 리스트

(23)

• 노드 구조

• 이중 연결 리스트의 구조

p == p->next->prev == p->prev->next

data

prev next

데 이 터 필 드

링 크 필 드

선 행 노 드 후 속 노 드

이중 연결 리스트 구조

typedef struct DblLinkedNode { Element data;

struct DblLinkedNode* prev;

struct DblLinkedNode* next;

} Node;

(24)

삽입연산

void insert_next(Node *p, Node *n) {

if (n != NULL) { n->prev = p;

n->next = p->next;

if (p->next != NULL)

(25)

( a ) 현 재 노 드 N을 삭 제 하 기 전 B

this

현 재 노 드

N C

( b ) 삭 제 후 B

this

현 재 노 드

N C

( 2 ) ( 1 )

삭제연산

void remove_curr(Node *n) {

if (n->prev != NULL)

n->prev->next = n->next;

if (n->next != NULL)

n->next->prev = n->prev;

}

(26)

전체 프로그램

void main() {

init_list();

insert(0, 10);

insert(0, 20);

insert(1, 30);

insert(size(), 40);

insert(2, 50);

print_list("이중연결리스트로 구현한 List(삽입x5)");

replace(2, 90);

print_list("이중연결리스트로 구현한 List(교체x1)");

delete(2);

delete(size() - 1);

delete(0);

print_list("이중연결리스트로 구현한 List(삽입x3)");

clear_list();

(27)

연결 리스트의 응용 : 라인 편집기

(28)

(1) 한 라인 삽입: 행 번호와 문자열을 입력 (2) 한 라인 삭제: 행 번호를 입력

(3) 한 라인 변경: 행 번호와 문자열을 입력 (4) 현재 내용 출력: 현재 모든 행을 출력 (5) 파일 입력: 지정된 파일 읽기

(6) 파일 출력: 지정된 파일로 저장

라인 편집기 기능

typedef struct Line {

char str[MAX_CHAR_PER_LINE];

} Line;

typedef Line Element;

(29)

실행 결과 1

(30)

실행 결과 2

(31)

참조

관련 문서

-하나의 공간에 시각적, 공간적 연속성이 어느 정도 있음.. 2)공간과 공간 사이에 공유공간 두어 연결. -맞물린 두 공간에

 연결 리스트의 경우 원소의 수에 무관하게 언제나 같은

네트워크 계층은 페이로드로 받아 헤더를 추가하여 데이터그램 또는 패킷이라는 네트워크 계층 패킷으로 만들어 링크 계층에 전달. 링크 계층은 페이로드로 받아

™ 정적 링크 (Static link) Return address Access link. ™ 비지역변수

 사이원반에 의해 각각의 근육세포들이

피겨사상 실내링크 처음 등장 동하계 올림픽 석권선수 탄생 -미국 이건(복싱, 봅슬레이).

파워 서플라이의 출력단자로부터 부하원을 연결할 경우 부하 연결 리드선에 전압 l i 이 파워 서플라이의 출력단자로부터 부하원을 연결할 경우 부하 연결

노드(Node)- 노드들은 블 록체인 네트워크 상에 연결 되어 있는 개개의 주체들이 며, 만일 당신이 블록체인 네트워크에 참여하게 되면