SlideShare a Scribd company logo
Linear List
- Linked List -
Geun-Hyung Kim
UMCL @ Dong-Eui University
리스트 (List) 개념
리스트 / 선형리스트
순서가 있는 항목의 모임
기본 연산: 추가(add), 제거(delete), 검색(search) 등
리스트를 구현하는 대표적인 방법: 배열, 연결리스트
배열
구현이 간단하고 효율적임 - 배열의 인덱스 번호로 저장공간 접근
가능
리스트의 크기가 고정 - 저장공간 재 할당이 필요
리스트의 중간에 항목을 추가/삭제 시 다른 항목을 옮겨야 함
연결리스트
리스트의 중간에 항목을 추가/삭제 시 다른 항목을 옮길 필요 없음
링크 필드를 위한 추가 저장 공간이 필요
리스트의 중간 항목을 바로 접근하는 것이 불가능
배열과 연결 리스트
Tuesday
Friday
Wednesday
Monday
예) 이번주 약속 목록
배열
100
101
102
103
104
105
106
107
108
109
110
Tuesday
Monday
Wednesday
Friday
100
101
102
103
104
105
106
107
108
109
110
107
NULL
103
105
연결 리스트 (head:101)
배열 리스트의 추가 제거
Tuesday
Friday
Wednesda
yMonday
100
101
102
103
104
105
106
107
108
109
110
Tuesday
Friday
Wednesda
yMonday
100
101
102
103
104
105
106
107
108
109
110
add ‘Saturday’
on 2nd position
Tuesday
Saturday
Friday
Wednesda
yMonday
100
101
102
103
104
105
106
107
108
109
110
delete ‘Friday’
Tuesday
Saturday
Wednesda
yMonday
Tuesday
Saturday
Wednesda
y
Monday
Tuesday
Friday
Wednesda
y
Monday
Tuesday
Friday
Wednesda
yMonday
Tuesday
Friday
Wednesda
yMonday
Tuesday
Satursday
Friday
Wednesda
yMonday
Tuesday
Satursday
Wednesda
yMonday
연결 리스트의 추가 제거
Tuesday
Monday
Wednesday
Friday
100
101
102
103
104
105
106
107
108
109
110
107
NULL
103
105
연결 리스트 (head:101)
Tuesday
Monday
Wednesday
Friday
Saturday
100
101
102
103
104
105
106
107
108
109
110
108
NULL
103
105
107
Tuesday
Monday
Wednesday
Saturday
100
101
102
103
104
105
106
107
108
109
110
108
NULL
103
105
add ‘Saturday’
on 2nd position
delete ‘Friday’
노드 (node)
노드 (Node)
노드는 리스트를 연결 리스트로 구현할 때 리스트의 각 요소
(element)의 정보를 저장공간에 저장하는 단위
각 노드는 실제 정보를 저장하는 데이터 필드와 다른 노드를
가리키는 링크 필드로 구성
data
link
Tuesday data
link
Saturday data
link
Wednesday data
link
Monday
NULL
head
연결리스트의 마지막 노드의
링크 필드는 NULL 값을 갖는다.
연결리스트의 첫 노드의 주소는
head pointer에 별도로 저장하여야 한다.
연결리스트를 구성하는 노드의 링크 필드는
다음 노드의 주소를 가리킨다.
노드의 C 언어 구현
struct node {
int data;
struct node *link;
}
데이터 필드 (정수 값 저장)
링크 필드
(sturct node 자료형의 주소를 저장하는 변수)
노드 구조체 정의
(새로운 자료형 정의)
typedef struct node ListNode;
ListNode *head;
struct node 자료형을 ListNode 자료형으로 재 정의
head 포인터 변수 선언
동적 메모리 할당
typedef struct node {
int data;
struct node *link;
} ListNode;
ListNode *p1;
p1 = (ListNode *)malloc(sizeof(ListNode)):
구조체의 정의와 동시에
새로운 ListNode 자료형 정의
예제 프로그램
int main()
{
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head->data = 10;
head->link = NULL;
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 20;
newNode->link = NULL;
head->link = newNode;
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 30;
newNode->link = NULL;
head = newNode;
ListNode *p = head;
while(p!=NULL) {
printf(“%dn”, p->data);
p = p->link;
}
}
NULL10
head
int main()
{
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head->data = 10;
head->link = NULL;
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 20;
newNode->link = NULL;
head->link = newNode;
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 30;
newNode->link = NULL;
head = newNode;
ListNode *p = head;
while(p!=NULL) {
printf(“%dn”, p->data);
p = p->link;
}
}
예제 프로그램
10head
NULL20newNode
int main()
{
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head->data = 10;
head->link = NULL;
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 20;
newNode->link = NULL;
head->link = newNode;
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 30;
newNode->link = head;
head = newNode;
ListNode *p = head;
while(p!=NULL) {
printf(“%dn”, p->data);
p = p->link;
}
}
예제 프로그램
10head
NULL20
newNode 30
int main()
{
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head->data = 10;
head->link = NULL;
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 20;
newNode->link = NULL;
head->link = newNode;
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 30;
newNode->link = head;
head = newNode;
ListNode *p = head;
while(p!=NULL) {
printf(“%dn”, p->data);
p = p->link;
}
}
예제 프로그램
10
head
NULL20
p 30
30
10
20
예제 프로그램
int main()
{
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head->data = 10;
head->link = NULL;
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 20;
newNode->link = NULL;
head->link = newNode;
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 30;
newNode->link = NULL;
head = newNode;
ListNode *p = head;
while(p != NULL) {
printf(“%dn”, p->data);
p = p->link;
}
}
연결리스트 맨 앞에 노드 추가 하기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
(1)새로운 노드를 만들고 데이터를 저장한다.
data
link
40
(2) 새로운 노드의 link 필드가 현재의 head 노드를 가리키도록 한다.
(3) 새로운 노드를
새로운 head 노드로 한다.
연결리스트 맨 앞에 노드 추가 하기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
data
link
40
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 40;
head = newNode;
newNode->link = head;
연결리스트 맨 앞에 노드 추가 하기
함수 정의(구현 1)
반환 자료 형: 없음
함수 이름: insertFirst
입력 파러미터(1): 저장할 정수 값
void insertFirst(int item)
{
ListNode *node = (ListNode *) malloc(sizeof(ListNode));
node->data = item;
node->link = head;
head = node;
}
Q) head는 어디에 있나 ?
모든 함수에서 직접 접근이 가능하도록 전역 변수로 선언되어 있음
함수호출 예: insertFirst(10);
연결리스트 맨 앞에 노드 추가 하기
반환 자료 형: 없음
함수 이름: insertFirst
입력 파러미터(2): 저장할 정수 값, 첫 노드의 가리키는 head 포인터 변수의 주소
void insertFirst(ListNode **ptrHead, int item)
{
ListNode *node = (ListNode *) malloc(sizeof(ListNode));
node->data = item;
node->link = *ptrHead;
*ptrHead = node;
}
함수호출 예: insertFirst(&head, 10);
첫 노드를 가리키는 head 포인터가 로컬 변수로 선언되어 있음
Q) head의 정보를 전달할 때 **ptrHead를 사용하는 이유는 ?
head 포인터의 값을 insertFirst() 함수 내에서 변경되어야 하고 함수 밖에서도
변경이 반영되어야 하기 때문에 head 포인터의 주소를 전달해야 하므로
함수 정의(구현 2)
연결리스트 맨 앞에 노드 추가 하기
반환 자료 형: ListNode 자료를 가리키는 주소 값
함수 이름: insertFirst
입력 파러미터(2): 저장할 정수 값, 첫 노드의 가리키는 head의 값
ListNode *insertFirst(ListNode *head, int item)
{
ListNode *node = (ListNode *) malloc(sizeof(ListNode));
node->data = item;
node->link = head;
return node;
}
함수호출 예: head = insertFirst(head, 10);
함수 정의(구현 3)
특정 노드 뒤에 새로운 노드 추가 하기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
(1)새로운 노드를 만들고 데이터를 저장한다.
data
link
40
(2) 새로운 노드의 link 필드가
현재의 head 노드를 가리키도록 한다.
(3) 새로운 노드를
prev의 다음 노드로 설정한다.
prev
특정 노드 뒤에 새로운 노드 추가 하기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
data
link
40
prev
newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->data = 40;
prev->link = newNode;
newNode->link = prev->link;
특정 노드 뒤에 새로운 노드 추가 하기
특정 노드 뒤에 새로운 노드 추가 하기특정 노드 뒤에 새로운 노드 추가 하기
반환 자료 형: 없음
함수 이름: insertAfterNode
입력 파러미터(2): 저장할 정수 값, 데이터를 저장할 위치 전 노드의 주소 값
void insertAfterNode(ListNode *prev, int item)
{
ListNode *node = (ListNode *) malloc(sizeof(ListNode));
node->data = item;
node->link = prev->link;
prev->link = node;
}
함수 정의(구현)
두가지 노드 추가 기능 통합
반환 자료 형: 없음
함수 이름: insertNode
입력 파러미터(3): head 포인터 변수의 저장 주소, 저장할 위치 앞의 노드 주소,
새로운 노드의 주소
함수 정의(구현)
void insertNode(ListNode** phead, ListNode* p, ListNode* newNode)
{
if(*phead == NULL){ //공백 리스트
newNode->link = NULL;
*phead = newNode;
}
else if(p == head){ //p가 NULL로 리스트의 첫번째 노드에 삽입
newNode->link = *phead;
*phead = newNode;
}
else{ //p 다음에 삽입
newNode->link = p->link;
p->link = newNode;
}
}
연결리스트의 첫번째 노드 삭제
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head head 가 두번 째 노드를 가리키도록 함
head = head->link;
연결리스트의 첫번째 노드 삭제
반환 자료 형: 삭제한 노드의 주소
함수 이름: removeFirst
입력 파러미터(0): 없음 (head가 전역변수 일때)
ListNode *removeFirst()
{
if (head == NULL)
return NULL;
else {
ListNode *node = head->link;
head = head->link;
return node;
}
}
함수 정의(구현 1)
연결리스트의 첫번째 노드 삭제
반환 자료 형: 삭제한 노드의 주소
함수 이름: removeFirst
입력 파러미터(1): head 포인터의 주소 (head 가 로컬 변수 일때)
ListNode *removeFirst(ListNode **head)
{
if (*head == NULL)
return NULL;
else {
ListNode *node = *head->link;
*head = *head->link;
return node;
}
}
함수 정의(구현 2)
특정 노드 뒤의 노드를 삭제 하기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
prev
prev 노드가
prev 노드가 가리키는 노드의
다음 노드를 가리키도록 한다
반환 자료 형: 삭제한 노드의 주소
함수 이름: removeAfter
입력 파러미터(2): head 포인터 변수의 주소 (head 가 로컬 변수 일때), 데
이터를 삭제할 노드의 전 노드 주소 값
함수 정의(구현)
특정 노드 뒤의 노드를 삭제 하기
ListNode *removeAfter(ListNode **head, ListNode *prev)
{
ListNode *node = prev->link;
if (*head == NULL)
return NULL;
else if (node == NULL)
return NULL;
else {
prev->link = node->link;
return node;
}
}
연결 리스트 순회하기
data
link
30 data
link
20 dat
lin
10 data
link
100
NULL
head
p
연결리스트 순회는 리스트의 모든 노드를 처음부터 순차적으로 방문하는 것을 뜻한다.
각 노드가 다음 노드의 데이터가 저장된 주소 정보를 가지고 있으므로 이를 이용하여
모든 노드를 순회할 수 있다.
연결리스트 순회하기
반환 자료 형: 없음
함수 이름: traverse
입력 파러미터(1): head 포인터 변수에 저장된 값
ListNode traverse(ListNode *head)
{
ListNode *p = head;
while (p != NULL) {
p = p->link;
}
}
함수 정의(구현)
연결리스트에서 원하는 값 탐색
반환 자료 형: ListNode 자료형의 주소
함수 이름: search
입력 파러미터(2): head 포인터에 저장된 값, 탐색하려는 정수 값
ListNode *search(ListNode *head, int value)
{
ListNode *p = head;
while (p != NULL) {
if (p->data == value) return p;
p = p->link;
}
return p;
}
함수 정의(구현)
두 연결 리스트의 연결
반환 자료 형: ListNode 자료형의 주소
함수 이름: concat
입력 파러미터(2): 첫 번째 연결리스트와 두번째 연결리스트의 head 값
ListNode *concat(ListNode *head1, ListNode *head2)
{
ListNode *p;
if(head1 == NULL) return head2;
else if (head2 == NULL) return head1;
else {
p = head1;
while (p->link != NULL) {
p = p->link;
}
p->link = head2;
return head1;
}
}
함수 정의(구현)
연결리스트를 역순으로 만들기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
qr
알고리즘 고찰
1. 첫 노드의 link 값(r->link) 을 NULL 로 설정
NULL
2. 두번째 노드의 link 값(q->link)을 이전의 노드(r)로 설정
문제 발생: 다음 링크에 대한 정보가 없어짐
해결방안: 2의 link 값을 변경하기 전에 link 값 (p) 을 저장해 놓아야 함
p
1-1. 두번째 노드(q)의 다음 노드를 저장 (p)
3. p, q, r을 모두 하나씩 오른쪽을 이동 r = q;
q = p;
p = p->link;
q->link = r;
연결리스트를 역순으로 만들기
data
link
30 data
link
20 data
link
10 data
link
100
NULL
head
p
p=head;
q=Null;
q
q=p;
p=p->link;
r=q;
1. 초기 상태
q->link=r;
NULL
r
NULL
r=q;
q=p;
p=p->link;
q->link=r;
r=q;
q=p;
p=p->link;
q->link=r;
r=q;
q=p;
p=p->link;
q->link=r;
연결리스트를 역순으로 만들기
반환 자료 형: ListNode 자료형의 주소
함수 이름: reverse
입력 파러미터(1): head 포인터에 저장된 값
ListNode *reverse(ListNode *head)
{
ListNode *p, *q, *r;
q=NULL;
p=head;
while (p!=NULL){
r=q;
q=p;
p=p->link;
q->link=r;
}
return q;
}
함수 정의(구현)
새로운 노드를 새롭게 생성하는 함수
반환 자료 형: 동적으로 생성한 노드의 주소
함수 이름: createNode
입력 파러미터(2): 저장할 데이터, 노드에 연결할 다른 노드 주소
ListNode *createNode(int data, ListNode *link)
{
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
if(newNode == NULL)
error(“memory allocation error”);
newNode->data = data;
newNode->link = link;
return newNode;
}
함수 정의(구현)
원형 연결 리스트
- Circular Linked List -
원형 연결 리스트
data
link
30 data
link
20 data
link
10 data
link
100
head
원형 연결 리스트
마지막 노드가 첫 번째 노드를 가리키는 연결 리스트
data
link
30 data
link
20 data
link
10 data
link
100
head
원형 연결 리스트 처음에 노드 추가
newNode->link = head->link;
head->link = newNode;
data
link
30 data
link
20 data
link
10 data
link
100
head
data
link
40
원형 연결 리스트 처음에 노드 추가
반환 자료 형: 없음
함수 이름: insertFirst2Circular
입력 파러미터(2): head 포인터 변수의 주소, 새로운 노드
void insertFirst2Circular(ListNode **phead, ListNode *newNode)
{
if (*phead == NULL){ // 공백 리스트
*phead = newNode;
newNode->link = newNode;
}
else{
newNode->link = *phead->link;
*phead->link = newNode;
}
}
함수 정의(구현)
원형 연결 리스트 마지막에 노드 추가
data
link
30 data
link
20 data
link
10 data
link
100
head
data
link
40
newNode->link = head->link;
head->link = newNode;
head = newNode;
원형 연결 리스트 마지막에 노드 추가
반환 자료 형: 없음
함수 이름: insertLast2Circular
입력 파러미터(2): head 포인터 변수의 주소, 새로운 노드
void insertLast2Circular(ListNode **phead, ListNode *newNode)
{
if (*phead == NULL){ // 공백 리스트
*phead = newNode;
newNode->link = newNode;
}
else{
newNode->link = *phead->link;
*phead->link = newNode;
*phead = newNode;
}
}
함수 정의(구현)
원형 연결 리스트 순회하기
data
link
30 data
link
20 data
link
10 data
link
100
head
p
순회 종료 조건
p->link == head
ListNode traverse(ListNode *head)
{
ListNode *p = head;
while (p->link != head) {
p = p->link;
}
}
연결리스트 응용
- 다항식 -
연결 리스트 응용: 다항식 표현
다항식
p(n)=anxn+an-1xn-1+…+a0
연결리스트를 이용하여 하나의 다항식을 표현하는 구조
체 (Polynomial)를 정의
다항식을 항들의 연결 리스트로 표현
항 들은 차수의 내림차순으로 정렬하여 저장하고 동일
차수의 항은 2개 이상 가지지 않으며 계수가 0인 항은
존재하지 않음
하나의 항은 계수와 지수로 표현하며 하나의 항도 구조
체(Term)로 표현
다항식 표현 예
coef
link
3
12expo
A(x)=3x12+4x8+1
coef
link
4
8expo
coef
link
1
0
NULL
expo
Term Term Term
name
size
A
3
first
Polynomial
구조체 Term
typedef struct Term {
int coef;
int expo;
struct Term *link;
}Term;
구조체 Polynomial
typedef struct Polynomial {
char name[20];
Term *first;
int size;
} Polynomial;
새로운 항목 생성하기
Term *createTerm(int coef, int expo) {
Term *term = (Term *)malloc(sizeof(Term));
term->coef = coef;
term->expo = expo;
term->link = NULL;
return term;
}
Polynomial *createPolynomial(char* name) {
Polynomial *poly = (Polynomial *)malloc(sizeof(Polynomial));
strcpy(poly->name, name);
term->size = 0;
term->first = NULL;
return poly;
}
다항식에 항목 추가하기
coef
link
3
12expo
coef
link
4
8expo
coef
link
1
0
NULL
expo
Term Term Term
name
size
A
3
first
Polynomial
addTermtoPloy(int c, int e, Polynomial *p);
다항식 p에 차수가 e이고 계수가 c인 항을 더하기
알고리즘 개요
추가하려는 항의 차수가 다항식에 있으면, coef 값에 계수 값을 더함
추가하려는 항의 차수가 다항식에 없으면, Term을 생성후 값을 대입하고 올바
른 위치에 추가
다항식에 항목 추가하기
coef
link
3
12expo
coef
link
4
8expo
coef
link
1
0
NULL
expo
Term Term Term
name
size
A
3
first
Polynomial
새로운 항이 추가되는 경우 : 6x10 을 추가하는 경우
coef
link
6
10
NULL
expo
Term *cur = p->first, *prev = null;
cur
while(cur != NULL && cur->expo > e){
prev = cur;
cur = cur->link;
}
prev
prev->link = newTerm;
newTerm->link =cur;
void addTermtoPoly(int c, int e, Polynomial *p) {
if (c ==0 || p == NULL) return;
Term *cur = p->first, *prev =NULL;
while (cur != NULL && cur->expo > e) {
prev = cur;
cur = cur->link;
}
if (cur != NULL && cur->expo == e) {
cur->coef += c;
if(cur->coef == 0) {
if (prev == NULL) p->first = cur->link;
else prev->link = cur->link;
p->size--;
free(cur);
}
return;
}
Term *newTerm = createTerm(c, e);
if (prev == NULL) p->first = newTerm;
else {
prev->link = newTerm;
newTerm->link = cur;
}
p->size++;
}
다항식에 항목 추가하기 -구현
다항식 출력하기
void polyPrint(Polynomial *poly) {
Term *ptrTerm = poly->first;
for (int i = 0; i < poly->size; i++) {
printf("%dx^%d ", ptrTerm->coef, ptrTerm->expo);
if (i != poly->size -1) printf(" + ");
ptrTerm = ptrTerm->link;
}
printf("n");
}
다항식 삭제하기
void delPolynomial(Polynomial *poly) {
Term *ptrTerm = poly->first, *cur;
for (int i = 0; i < poly->size; i++) {
cur = ptrTerm;
ptrTerm = ptrTerm->link;
free(cur);
}
free(poly);
}
두 다항식 더하기다항식 더하기
Polynomial *addPoly(Polynomial *a, Polynomial *b) {
Term *pa = a->first, *pb = b->first, *newTerm;
int coef, expo;
Polynomial *result = createPolynomial(“sum”);
while (pa != NULL && pb != NULL) {
if (pa->expo > pb->expo) {
coef = pa->coef; expo = pa->expo;
addTermtoPoly(coef, expo, result);
pa = pa->link;
} else if (pa->expo == pb->expo) {
coef = pa->coef + pb->coef; expo = pa->expo;
addTermtoPoly(coef, expo, result);
pa = pa->link; pb = pb->link;
} else {
coef = pb->coef; expo = pb->expo;
addTermtoPoly(coef, expo, result);
pb = pb->link;
}
}
while (pa != NULL){addTermtoPoly(pa->coef, pa->expo, result); pa = pa->link;}
while (pb != NULL){addTermtoPoly(pb->coef, pb->expo, result); pb = pb->link;}
return result;
}
Summary of
Linked Lists
#ifndef _Linked_List_
#define _Linked_List_
ListNode *createNode(int data, ListNode *link);
void insertFirst(ListNode **ptrHead, int item);
void insertAfterNode(ListNode *prev, int item);
void insertNode(ListNode** phead, ListNode* p, ListNode* newNode);
ListNode *removeFirst(ListNode **head);
ListNode *removeAfter(ListNode **head, ListNode *prev);
ListNode traverse(ListNode *head);
ListNode *search(ListNode *head, int value);
ListNode *concat(ListNode *head1, ListNode *head2);
ListNode *reverse(ListNode *head);
#endif
Linked_List
Linked_List: 추가되어야 할 요소
int isEmpty(ListNode *ptrHead); // List가 비어 있는지 확인
int getLength(ListNode *ptrHead); // List의 Node 수 확인
// List에서 pos에 있는 Node를 반환
ListNode *getNodeAt(ListNode *ptrHead, int pos);
// List에서 pos에 있는 data를 반환
int getEntryAt(ListNode *ptrHead, int pos);
// List에서 주어진 위치에 데이터 삽입
void insertNodeAt(ListNode **ptrHead, int pos, int item);
// List의 마지막에 데이터 삽입
void insertLast(ListNode **ptrHead, int item);
// List에서 주어진 위치의 데이터를 삭제
ListNode *removeAt(ListNode **ptrHead, int pos);
// List의 모든 노드를 삭제
void removeAll(ListNode *ptrHead);
// List의 모든 노드의 데이터 출력
void printData(ListNode *ptrHead);
연결 리스트 응용
- line editor -
Line Editor
Editor Command 창에서 한 줄씩 입력하거나 삭제
라인 번호와 라인의 내용을 입력받아 지정된 위치에 저장
각 라인에 해당하는 텍스트를 연결 리스트 노드의 데이터로 처리
커서를 사용하지 않는 단순한 에디터
파일을 이용하여 문서를 저장 및 편집
Line Editor
파일 읽고 쓰기 위한 기본 함수
파일을 열고 닫는 함수: fopen, fclose
파일로 부터 데이터를 읽는 함수: fscanf, fgets, fread
파일로 데이터를 쓰는 함수: fprintf, fputs
Line Editor: fopen/fclose
fopen() 함수 프로토타입:
FILE* fopen(const char* filename, const char* mode);
FILE: _iobuf라는 구조체 (입출력장치에 대한 관련 정보 저장)
filename: 읽거나 쓰고자 하는 파일 이름
mode (파일 액세스 모드): r, w, a, r+, w+, a+, t , b
fclose() 함수 프로토타입:
int fclose(File* fprt);
반환 데이터: 파일이 오류없이 닫히면 0을 리턴
fopen() 함수로 파일을 열었으면 작업을 완료 후 반드시 fclose()함수로 닫아야 함
입력 파라미터: 파일포인터
입력 파라미터:
반환 데이터: 파일 포인터
Line Editor / fgets()
fgets() 함수 프로토타입:
char* fgets(char *string, int n, FILE* stream);
반환 데이터: 읽은 문자열의 포인터, 더 읽을 내용이 없거나 에러 시 NULL 반환
입력 파라미터(3): 파일 데이터를 읽어 저장할 버퍼의 포인터 (string),
읽을 최대 문자 수 +1 (n),
오픈한 FILE 구조체 (_iobuf 구조체) 포인터 (stream)
#include <stdio.h>
int main(){
char buf[20];
char *line;
FILE *fptr = fopen(“data.txt”,”r”);
if(fptr == NULL) {
// 에러 처리
}
else {
while ((line = fgets(buf, sizeof(buf), fptr)) != NULL) {
printf(“%s”,line);
}
fclose(fptr);
}
return 0;
}
파일에서 읽은 데이터 포인터
파일 끝이나 ‘n’ 문자까지 읽음
라인 끝(CR/LF)을 읽으면 개행 문자 ‘n’으로 변환
읽은 문자들 끝에 NULL 문자 추가
오픈한 파일에서 문자열을 한 줄씩 읽어옴
Line Editor: fputs()
fputs() 함수 프로토타입:
int fputs(const char *string, FILE* stream);
반환 데이터: 성공 시 0 또는 양수, 실패 시 EOF(-1)
입력 파라미터(2): 파일에 쓸 NULL로 끝나는 문자열 버퍼의 포인터 (string),
오픈한 FILE 구조체 (_iobuf 구조체) 포인터 (stream)
개방된 파일에 문자열을 라인 단위로 저장
int main( ){
char buf[255];
FILE *fptr = fopen("data1.txt", "w");
int result;
if(fptr == NULL) {
// 에러 처리 코드
}
else {
for (int i = 0; i < 5; i++ ) {
sprintf(buf, "[line:%d] %s n", i+1, in[i]);
result = fputs(buf, fptr);
if (result == -1) printf ("file write errorn");
}
fclose(fptr);
}
}
쓰기 모드
파일에 저장될 문자 한 줄
개행 문자 ‘n’ 문자를 라인 끝(CR/LF)로 변환
파일 포인터

More Related Content

What's hot

말의여행
말의여행말의여행
말의여행mil23
 
Project#2말의여행 Hwp
Project#2말의여행 HwpProject#2말의여행 Hwp
Project#2말의여행 HwpKimjeongmoo
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
happychallenge
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03chl132435
 
2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdfkd19h
 
Python Programming: Function
Python Programming: FunctionPython Programming: Function
Python Programming: Function
Chan Shik Lim
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
Circulus
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작
Terry Cho
 
Haskell study 13
Haskell study 13Haskell study 13
Haskell study 13
Nam Hyeonuk
 
하스켈 프로그래밍 입문
하스켈 프로그래밍 입문하스켈 프로그래밍 입문
하스켈 프로그래밍 입문
Kwang Yul Seo
 
Haskell study 5
Haskell study 5Haskell study 5
Haskell study 5
Nam Hyeonuk
 
종이접기(fold) 프로그래밍
종이접기(fold) 프로그래밍종이접기(fold) 프로그래밍
종이접기(fold) 프로그래밍
Kwang Yul Seo
 
알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols
seungdols
 
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Circulus
 
하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2
Kwang Yul Seo
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
Circulus
 

What's hot (20)

자료구조02
자료구조02자료구조02
자료구조02
 
말의여행
말의여행말의여행
말의여행
 
Project#2말의여행 Hwp
Project#2말의여행 HwpProject#2말의여행 Hwp
Project#2말의여행 Hwp
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03
 
2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf
 
자구3번
자구3번자구3번
자구3번
 
Python Programming: Function
Python Programming: FunctionPython Programming: Function
Python Programming: Function
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작
 
Haskell study 13
Haskell study 13Haskell study 13
Haskell study 13
 
강의자료4
강의자료4강의자료4
강의자료4
 
자료구조03
자료구조03자료구조03
자료구조03
 
하스켈 프로그래밍 입문
하스켈 프로그래밍 입문하스켈 프로그래밍 입문
하스켈 프로그래밍 입문
 
Haskell study 5
Haskell study 5Haskell study 5
Haskell study 5
 
종이접기(fold) 프로그래밍
종이접기(fold) 프로그래밍종이접기(fold) 프로그래밍
종이접기(fold) 프로그래밍
 
알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols
 
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리
 
하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
 

Viewers also liked

7. sorting
7. sorting7. sorting
7. sorting
Geunhyung Kim
 
Open edx 통합테스트 보고서
Open edx 통합테스트 보고서Open edx 통합테스트 보고서
Open edx 통합테스트 보고서
sam Cyberspace
 
CDLP
CDLPCDLP
Curriculam Vitae_ Dhyanesh Singh
Curriculam Vitae_ Dhyanesh SinghCurriculam Vitae_ Dhyanesh Singh
Curriculam Vitae_ Dhyanesh Singh
Dhyanesh Singh
 
Arizona divorce law
Arizona divorce lawArizona divorce law
Arizona divorce law
Thomas Mastromatto NMLS #145824
 
LinkedIn Profile.doc-SABARI
LinkedIn Profile.doc-SABARILinkedIn Profile.doc-SABARI
LinkedIn Profile.doc-SABARI
Sabari parasuram G
 
Speech 5 -tis the season (1)
Speech 5 -tis the season (1)Speech 5 -tis the season (1)
Speech 5 -tis the season (1)
aas24118
 
FINAL RR INFO GRAPH
FINAL RR INFO GRAPHFINAL RR INFO GRAPH
FINAL RR INFO GRAPH
Mark Richard Dagel
 
Q4
Q4Q4
Tibau,carmen
Tibau,carmenTibau,carmen
Tibau,carmen
ESO1
 
Arizona supreme court divorce booklet
Arizona supreme court divorce bookletArizona supreme court divorce booklet
Arizona supreme court divorce booklet
Thomas Mastromatto NMLS #145824
 
اشتباهات امنیتی در سفر
اشتباهات امنیتی در سفراشتباهات امنیتی در سفر
اشتباهات امنیتی در سفر
Aila Sayyadi
 
6. binary tree
6. binary tree6. binary tree
6. binary tree
Geunhyung Kim
 
Otitis media crónica supurada
Otitis media crónica supuradaOtitis media crónica supurada
Otitis media crónica supurada
DianaBlasto
 
School Prospectus Research
School Prospectus ResearchSchool Prospectus Research
School Prospectus Research
danieswallow98
 
Film poster analysis success criteria
Film poster analysis   success criteriaFilm poster analysis   success criteria
Film poster analysis success criteria
CoombeMedia1
 
A Lei do Amor
A Lei do AmorA Lei do Amor

Viewers also liked (17)

7. sorting
7. sorting7. sorting
7. sorting
 
Open edx 통합테스트 보고서
Open edx 통합테스트 보고서Open edx 통합테스트 보고서
Open edx 통합테스트 보고서
 
CDLP
CDLPCDLP
CDLP
 
Curriculam Vitae_ Dhyanesh Singh
Curriculam Vitae_ Dhyanesh SinghCurriculam Vitae_ Dhyanesh Singh
Curriculam Vitae_ Dhyanesh Singh
 
Arizona divorce law
Arizona divorce lawArizona divorce law
Arizona divorce law
 
LinkedIn Profile.doc-SABARI
LinkedIn Profile.doc-SABARILinkedIn Profile.doc-SABARI
LinkedIn Profile.doc-SABARI
 
Speech 5 -tis the season (1)
Speech 5 -tis the season (1)Speech 5 -tis the season (1)
Speech 5 -tis the season (1)
 
FINAL RR INFO GRAPH
FINAL RR INFO GRAPHFINAL RR INFO GRAPH
FINAL RR INFO GRAPH
 
Q4
Q4Q4
Q4
 
Tibau,carmen
Tibau,carmenTibau,carmen
Tibau,carmen
 
Arizona supreme court divorce booklet
Arizona supreme court divorce bookletArizona supreme court divorce booklet
Arizona supreme court divorce booklet
 
اشتباهات امنیتی در سفر
اشتباهات امنیتی در سفراشتباهات امنیتی در سفر
اشتباهات امنیتی در سفر
 
6. binary tree
6. binary tree6. binary tree
6. binary tree
 
Otitis media crónica supurada
Otitis media crónica supuradaOtitis media crónica supurada
Otitis media crónica supurada
 
School Prospectus Research
School Prospectus ResearchSchool Prospectus Research
School Prospectus Research
 
Film poster analysis success criteria
Film poster analysis   success criteriaFilm poster analysis   success criteria
Film poster analysis success criteria
 
A Lei do Amor
A Lei do AmorA Lei do Amor
A Lei do Amor
 

Similar to 3. linked list

연결리스트 박진호
연결리스트 박진호연결리스트 박진호
연결리스트 박진호jinho park
 
연결 리스트(기초)
연결 리스트(기초)연결 리스트(기초)
연결 리스트(기초)
Lee Geonhee
 
[Swift] Data Structure - Linked List
[Swift] Data Structure - Linked List[Swift] Data Structure - Linked List
[Swift] Data Structure - Linked List
Bill Kim
 
2012 Ds A1 03
2012 Ds A1 032012 Ds A1 03
2012 Ds A1 03seonhyung
 
자료구조 Project3
자료구조 Project3자료구조 Project3
자료구조 Project3KoChungWook
 
Data Structure. Linked List
Data Structure. Linked ListData Structure. Linked List
Data Structure. Linked List
Seung-chan Baeg
 
Project#3다항식의연산 Hwp
Project#3다항식의연산 HwpProject#3다항식의연산 Hwp
Project#3다항식의연산 HwpKimjeongmoo
 
자료구조3보고서
자료구조3보고서자료구조3보고서
자료구조3보고서KimChangHoen
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
S.O.P.T - Shout Our Passion Together
 
자료구조04
자료구조04자료구조04
자료구조04
herojoon1378
 
[Swift] Data Structure - Heap
[Swift] Data Structure - Heap[Swift] Data Structure - Heap
[Swift] Data Structure - Heap
Bill Kim
 
파이썬 크롤링 모듈
파이썬 크롤링 모듈파이썬 크롤링 모듈
파이썬 크롤링 모듈
Yong Joon Moon
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선daewon jeong
 
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Fp basic-kotlin
Fp basic-kotlinFp basic-kotlin
Fp basic-kotlin
Myeongin Woo
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서mil23
 

Similar to 3. linked list (18)

연결리스트 박진호
연결리스트 박진호연결리스트 박진호
연결리스트 박진호
 
연결 리스트(기초)
연결 리스트(기초)연결 리스트(기초)
연결 리스트(기초)
 
[Swift] Data Structure - Linked List
[Swift] Data Structure - Linked List[Swift] Data Structure - Linked List
[Swift] Data Structure - Linked List
 
2012 Ds A1 03
2012 Ds A1 032012 Ds A1 03
2012 Ds A1 03
 
자료구조 Project3
자료구조 Project3자료구조 Project3
자료구조 Project3
 
Data Structure. Linked List
Data Structure. Linked ListData Structure. Linked List
Data Structure. Linked List
 
Project#3다항식의연산 Hwp
Project#3다항식의연산 HwpProject#3다항식의연산 Hwp
Project#3다항식의연산 Hwp
 
자료구조3보고서
자료구조3보고서자료구조3보고서
자료구조3보고서
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
 
자료구조04
자료구조04자료구조04
자료구조04
 
자구4번
자구4번자구4번
자구4번
 
[Swift] Data Structure - Heap
[Swift] Data Structure - Heap[Swift] Data Structure - Heap
[Swift] Data Structure - Heap
 
파이썬 크롤링 모듈
파이썬 크롤링 모듈파이썬 크롤링 모듈
파이썬 크롤링 모듈
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선
 
2012 Ds 06
2012 Ds 062012 Ds 06
2012 Ds 06
 
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
Fp basic-kotlin
Fp basic-kotlinFp basic-kotlin
Fp basic-kotlin
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서
 

3. linked list

  • 1. Linear List - Linked List - Geun-Hyung Kim UMCL @ Dong-Eui University
  • 2. 리스트 (List) 개념 리스트 / 선형리스트 순서가 있는 항목의 모임 기본 연산: 추가(add), 제거(delete), 검색(search) 등 리스트를 구현하는 대표적인 방법: 배열, 연결리스트 배열 구현이 간단하고 효율적임 - 배열의 인덱스 번호로 저장공간 접근 가능 리스트의 크기가 고정 - 저장공간 재 할당이 필요 리스트의 중간에 항목을 추가/삭제 시 다른 항목을 옮겨야 함 연결리스트 리스트의 중간에 항목을 추가/삭제 시 다른 항목을 옮길 필요 없음 링크 필드를 위한 추가 저장 공간이 필요 리스트의 중간 항목을 바로 접근하는 것이 불가능
  • 3. 배열과 연결 리스트 Tuesday Friday Wednesday Monday 예) 이번주 약속 목록 배열 100 101 102 103 104 105 106 107 108 109 110 Tuesday Monday Wednesday Friday 100 101 102 103 104 105 106 107 108 109 110 107 NULL 103 105 연결 리스트 (head:101)
  • 4. 배열 리스트의 추가 제거 Tuesday Friday Wednesda yMonday 100 101 102 103 104 105 106 107 108 109 110 Tuesday Friday Wednesda yMonday 100 101 102 103 104 105 106 107 108 109 110 add ‘Saturday’ on 2nd position Tuesday Saturday Friday Wednesda yMonday 100 101 102 103 104 105 106 107 108 109 110 delete ‘Friday’ Tuesday Saturday Wednesda yMonday Tuesday Saturday Wednesda y Monday Tuesday Friday Wednesda y Monday Tuesday Friday Wednesda yMonday Tuesday Friday Wednesda yMonday Tuesday Satursday Friday Wednesda yMonday Tuesday Satursday Wednesda yMonday
  • 5. 연결 리스트의 추가 제거 Tuesday Monday Wednesday Friday 100 101 102 103 104 105 106 107 108 109 110 107 NULL 103 105 연결 리스트 (head:101) Tuesday Monday Wednesday Friday Saturday 100 101 102 103 104 105 106 107 108 109 110 108 NULL 103 105 107 Tuesday Monday Wednesday Saturday 100 101 102 103 104 105 106 107 108 109 110 108 NULL 103 105 add ‘Saturday’ on 2nd position delete ‘Friday’ 노드 (node)
  • 6. 노드 (Node) 노드는 리스트를 연결 리스트로 구현할 때 리스트의 각 요소 (element)의 정보를 저장공간에 저장하는 단위 각 노드는 실제 정보를 저장하는 데이터 필드와 다른 노드를 가리키는 링크 필드로 구성 data link Tuesday data link Saturday data link Wednesday data link Monday NULL head 연결리스트의 마지막 노드의 링크 필드는 NULL 값을 갖는다. 연결리스트의 첫 노드의 주소는 head pointer에 별도로 저장하여야 한다. 연결리스트를 구성하는 노드의 링크 필드는 다음 노드의 주소를 가리킨다.
  • 7. 노드의 C 언어 구현 struct node { int data; struct node *link; } 데이터 필드 (정수 값 저장) 링크 필드 (sturct node 자료형의 주소를 저장하는 변수) 노드 구조체 정의 (새로운 자료형 정의) typedef struct node ListNode; ListNode *head; struct node 자료형을 ListNode 자료형으로 재 정의 head 포인터 변수 선언
  • 8. 동적 메모리 할당 typedef struct node { int data; struct node *link; } ListNode; ListNode *p1; p1 = (ListNode *)malloc(sizeof(ListNode)): 구조체의 정의와 동시에 새로운 ListNode 자료형 정의
  • 9. 예제 프로그램 int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL; ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode; newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30; newNode->link = NULL; head = newNode; ListNode *p = head; while(p!=NULL) { printf(“%dn”, p->data); p = p->link; } } NULL10 head
  • 10. int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL; ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode; newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30; newNode->link = NULL; head = newNode; ListNode *p = head; while(p!=NULL) { printf(“%dn”, p->data); p = p->link; } } 예제 프로그램 10head NULL20newNode
  • 11. int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL; ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode; newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30; newNode->link = head; head = newNode; ListNode *p = head; while(p!=NULL) { printf(“%dn”, p->data); p = p->link; } } 예제 프로그램 10head NULL20 newNode 30
  • 12. int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL; ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode; newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30; newNode->link = head; head = newNode; ListNode *p = head; while(p!=NULL) { printf(“%dn”, p->data); p = p->link; } } 예제 프로그램 10 head NULL20 p 30 30 10 20
  • 13. 예제 프로그램 int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL; ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode; newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30; newNode->link = NULL; head = newNode; ListNode *p = head; while(p != NULL) { printf(“%dn”, p->data); p = p->link; } }
  • 14. 연결리스트 맨 앞에 노드 추가 하기 data link 30 data link 20 data link 10 data link 100 NULL head (1)새로운 노드를 만들고 데이터를 저장한다. data link 40 (2) 새로운 노드의 link 필드가 현재의 head 노드를 가리키도록 한다. (3) 새로운 노드를 새로운 head 노드로 한다.
  • 15. 연결리스트 맨 앞에 노드 추가 하기 data link 30 data link 20 data link 10 data link 100 NULL head data link 40 newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 40; head = newNode; newNode->link = head;
  • 16. 연결리스트 맨 앞에 노드 추가 하기 함수 정의(구현 1) 반환 자료 형: 없음 함수 이름: insertFirst 입력 파러미터(1): 저장할 정수 값 void insertFirst(int item) { ListNode *node = (ListNode *) malloc(sizeof(ListNode)); node->data = item; node->link = head; head = node; } Q) head는 어디에 있나 ? 모든 함수에서 직접 접근이 가능하도록 전역 변수로 선언되어 있음 함수호출 예: insertFirst(10);
  • 17. 연결리스트 맨 앞에 노드 추가 하기 반환 자료 형: 없음 함수 이름: insertFirst 입력 파러미터(2): 저장할 정수 값, 첫 노드의 가리키는 head 포인터 변수의 주소 void insertFirst(ListNode **ptrHead, int item) { ListNode *node = (ListNode *) malloc(sizeof(ListNode)); node->data = item; node->link = *ptrHead; *ptrHead = node; } 함수호출 예: insertFirst(&head, 10); 첫 노드를 가리키는 head 포인터가 로컬 변수로 선언되어 있음 Q) head의 정보를 전달할 때 **ptrHead를 사용하는 이유는 ? head 포인터의 값을 insertFirst() 함수 내에서 변경되어야 하고 함수 밖에서도 변경이 반영되어야 하기 때문에 head 포인터의 주소를 전달해야 하므로 함수 정의(구현 2)
  • 18. 연결리스트 맨 앞에 노드 추가 하기 반환 자료 형: ListNode 자료를 가리키는 주소 값 함수 이름: insertFirst 입력 파러미터(2): 저장할 정수 값, 첫 노드의 가리키는 head의 값 ListNode *insertFirst(ListNode *head, int item) { ListNode *node = (ListNode *) malloc(sizeof(ListNode)); node->data = item; node->link = head; return node; } 함수호출 예: head = insertFirst(head, 10); 함수 정의(구현 3)
  • 19. 특정 노드 뒤에 새로운 노드 추가 하기 data link 30 data link 20 data link 10 data link 100 NULL head (1)새로운 노드를 만들고 데이터를 저장한다. data link 40 (2) 새로운 노드의 link 필드가 현재의 head 노드를 가리키도록 한다. (3) 새로운 노드를 prev의 다음 노드로 설정한다. prev
  • 20. 특정 노드 뒤에 새로운 노드 추가 하기 data link 30 data link 20 data link 10 data link 100 NULL head data link 40 prev newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 40; prev->link = newNode; newNode->link = prev->link;
  • 21. 특정 노드 뒤에 새로운 노드 추가 하기 특정 노드 뒤에 새로운 노드 추가 하기특정 노드 뒤에 새로운 노드 추가 하기 반환 자료 형: 없음 함수 이름: insertAfterNode 입력 파러미터(2): 저장할 정수 값, 데이터를 저장할 위치 전 노드의 주소 값 void insertAfterNode(ListNode *prev, int item) { ListNode *node = (ListNode *) malloc(sizeof(ListNode)); node->data = item; node->link = prev->link; prev->link = node; } 함수 정의(구현)
  • 22. 두가지 노드 추가 기능 통합 반환 자료 형: 없음 함수 이름: insertNode 입력 파러미터(3): head 포인터 변수의 저장 주소, 저장할 위치 앞의 노드 주소, 새로운 노드의 주소 함수 정의(구현) void insertNode(ListNode** phead, ListNode* p, ListNode* newNode) { if(*phead == NULL){ //공백 리스트 newNode->link = NULL; *phead = newNode; } else if(p == head){ //p가 NULL로 리스트의 첫번째 노드에 삽입 newNode->link = *phead; *phead = newNode; } else{ //p 다음에 삽입 newNode->link = p->link; p->link = newNode; } }
  • 23. 연결리스트의 첫번째 노드 삭제 data link 30 data link 20 data link 10 data link 100 NULL head head 가 두번 째 노드를 가리키도록 함 head = head->link;
  • 24. 연결리스트의 첫번째 노드 삭제 반환 자료 형: 삭제한 노드의 주소 함수 이름: removeFirst 입력 파러미터(0): 없음 (head가 전역변수 일때) ListNode *removeFirst() { if (head == NULL) return NULL; else { ListNode *node = head->link; head = head->link; return node; } } 함수 정의(구현 1)
  • 25. 연결리스트의 첫번째 노드 삭제 반환 자료 형: 삭제한 노드의 주소 함수 이름: removeFirst 입력 파러미터(1): head 포인터의 주소 (head 가 로컬 변수 일때) ListNode *removeFirst(ListNode **head) { if (*head == NULL) return NULL; else { ListNode *node = *head->link; *head = *head->link; return node; } } 함수 정의(구현 2)
  • 26. 특정 노드 뒤의 노드를 삭제 하기 data link 30 data link 20 data link 10 data link 100 NULL head prev prev 노드가 prev 노드가 가리키는 노드의 다음 노드를 가리키도록 한다
  • 27. 반환 자료 형: 삭제한 노드의 주소 함수 이름: removeAfter 입력 파러미터(2): head 포인터 변수의 주소 (head 가 로컬 변수 일때), 데 이터를 삭제할 노드의 전 노드 주소 값 함수 정의(구현) 특정 노드 뒤의 노드를 삭제 하기 ListNode *removeAfter(ListNode **head, ListNode *prev) { ListNode *node = prev->link; if (*head == NULL) return NULL; else if (node == NULL) return NULL; else { prev->link = node->link; return node; } }
  • 28. 연결 리스트 순회하기 data link 30 data link 20 dat lin 10 data link 100 NULL head p 연결리스트 순회는 리스트의 모든 노드를 처음부터 순차적으로 방문하는 것을 뜻한다. 각 노드가 다음 노드의 데이터가 저장된 주소 정보를 가지고 있으므로 이를 이용하여 모든 노드를 순회할 수 있다.
  • 29. 연결리스트 순회하기 반환 자료 형: 없음 함수 이름: traverse 입력 파러미터(1): head 포인터 변수에 저장된 값 ListNode traverse(ListNode *head) { ListNode *p = head; while (p != NULL) { p = p->link; } } 함수 정의(구현)
  • 30. 연결리스트에서 원하는 값 탐색 반환 자료 형: ListNode 자료형의 주소 함수 이름: search 입력 파러미터(2): head 포인터에 저장된 값, 탐색하려는 정수 값 ListNode *search(ListNode *head, int value) { ListNode *p = head; while (p != NULL) { if (p->data == value) return p; p = p->link; } return p; } 함수 정의(구현)
  • 31. 두 연결 리스트의 연결 반환 자료 형: ListNode 자료형의 주소 함수 이름: concat 입력 파러미터(2): 첫 번째 연결리스트와 두번째 연결리스트의 head 값 ListNode *concat(ListNode *head1, ListNode *head2) { ListNode *p; if(head1 == NULL) return head2; else if (head2 == NULL) return head1; else { p = head1; while (p->link != NULL) { p = p->link; } p->link = head2; return head1; } } 함수 정의(구현)
  • 32. 연결리스트를 역순으로 만들기 data link 30 data link 20 data link 10 data link 100 NULL head qr 알고리즘 고찰 1. 첫 노드의 link 값(r->link) 을 NULL 로 설정 NULL 2. 두번째 노드의 link 값(q->link)을 이전의 노드(r)로 설정 문제 발생: 다음 링크에 대한 정보가 없어짐 해결방안: 2의 link 값을 변경하기 전에 link 값 (p) 을 저장해 놓아야 함 p 1-1. 두번째 노드(q)의 다음 노드를 저장 (p) 3. p, q, r을 모두 하나씩 오른쪽을 이동 r = q; q = p; p = p->link; q->link = r;
  • 33. 연결리스트를 역순으로 만들기 data link 30 data link 20 data link 10 data link 100 NULL head p p=head; q=Null; q q=p; p=p->link; r=q; 1. 초기 상태 q->link=r; NULL r NULL r=q; q=p; p=p->link; q->link=r; r=q; q=p; p=p->link; q->link=r; r=q; q=p; p=p->link; q->link=r;
  • 34. 연결리스트를 역순으로 만들기 반환 자료 형: ListNode 자료형의 주소 함수 이름: reverse 입력 파러미터(1): head 포인터에 저장된 값 ListNode *reverse(ListNode *head) { ListNode *p, *q, *r; q=NULL; p=head; while (p!=NULL){ r=q; q=p; p=p->link; q->link=r; } return q; } 함수 정의(구현)
  • 35. 새로운 노드를 새롭게 생성하는 함수 반환 자료 형: 동적으로 생성한 노드의 주소 함수 이름: createNode 입력 파러미터(2): 저장할 데이터, 노드에 연결할 다른 노드 주소 ListNode *createNode(int data, ListNode *link) { ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); if(newNode == NULL) error(“memory allocation error”); newNode->data = data; newNode->link = link; return newNode; } 함수 정의(구현)
  • 36. 원형 연결 리스트 - Circular Linked List -
  • 37. 원형 연결 리스트 data link 30 data link 20 data link 10 data link 100 head 원형 연결 리스트 마지막 노드가 첫 번째 노드를 가리키는 연결 리스트 data link 30 data link 20 data link 10 data link 100 head
  • 38. 원형 연결 리스트 처음에 노드 추가 newNode->link = head->link; head->link = newNode; data link 30 data link 20 data link 10 data link 100 head data link 40
  • 39. 원형 연결 리스트 처음에 노드 추가 반환 자료 형: 없음 함수 이름: insertFirst2Circular 입력 파러미터(2): head 포인터 변수의 주소, 새로운 노드 void insertFirst2Circular(ListNode **phead, ListNode *newNode) { if (*phead == NULL){ // 공백 리스트 *phead = newNode; newNode->link = newNode; } else{ newNode->link = *phead->link; *phead->link = newNode; } } 함수 정의(구현)
  • 40. 원형 연결 리스트 마지막에 노드 추가 data link 30 data link 20 data link 10 data link 100 head data link 40 newNode->link = head->link; head->link = newNode; head = newNode;
  • 41. 원형 연결 리스트 마지막에 노드 추가 반환 자료 형: 없음 함수 이름: insertLast2Circular 입력 파러미터(2): head 포인터 변수의 주소, 새로운 노드 void insertLast2Circular(ListNode **phead, ListNode *newNode) { if (*phead == NULL){ // 공백 리스트 *phead = newNode; newNode->link = newNode; } else{ newNode->link = *phead->link; *phead->link = newNode; *phead = newNode; } } 함수 정의(구현)
  • 42. 원형 연결 리스트 순회하기 data link 30 data link 20 data link 10 data link 100 head p 순회 종료 조건 p->link == head ListNode traverse(ListNode *head) { ListNode *p = head; while (p->link != head) { p = p->link; } }
  • 44. 연결 리스트 응용: 다항식 표현 다항식 p(n)=anxn+an-1xn-1+…+a0 연결리스트를 이용하여 하나의 다항식을 표현하는 구조 체 (Polynomial)를 정의 다항식을 항들의 연결 리스트로 표현 항 들은 차수의 내림차순으로 정렬하여 저장하고 동일 차수의 항은 2개 이상 가지지 않으며 계수가 0인 항은 존재하지 않음 하나의 항은 계수와 지수로 표현하며 하나의 항도 구조 체(Term)로 표현
  • 46. 구조체 Term typedef struct Term { int coef; int expo; struct Term *link; }Term;
  • 47. 구조체 Polynomial typedef struct Polynomial { char name[20]; Term *first; int size; } Polynomial;
  • 48. 새로운 항목 생성하기 Term *createTerm(int coef, int expo) { Term *term = (Term *)malloc(sizeof(Term)); term->coef = coef; term->expo = expo; term->link = NULL; return term; } Polynomial *createPolynomial(char* name) { Polynomial *poly = (Polynomial *)malloc(sizeof(Polynomial)); strcpy(poly->name, name); term->size = 0; term->first = NULL; return poly; }
  • 49. 다항식에 항목 추가하기 coef link 3 12expo coef link 4 8expo coef link 1 0 NULL expo Term Term Term name size A 3 first Polynomial addTermtoPloy(int c, int e, Polynomial *p); 다항식 p에 차수가 e이고 계수가 c인 항을 더하기 알고리즘 개요 추가하려는 항의 차수가 다항식에 있으면, coef 값에 계수 값을 더함 추가하려는 항의 차수가 다항식에 없으면, Term을 생성후 값을 대입하고 올바 른 위치에 추가
  • 50. 다항식에 항목 추가하기 coef link 3 12expo coef link 4 8expo coef link 1 0 NULL expo Term Term Term name size A 3 first Polynomial 새로운 항이 추가되는 경우 : 6x10 을 추가하는 경우 coef link 6 10 NULL expo Term *cur = p->first, *prev = null; cur while(cur != NULL && cur->expo > e){ prev = cur; cur = cur->link; } prev prev->link = newTerm; newTerm->link =cur;
  • 51. void addTermtoPoly(int c, int e, Polynomial *p) { if (c ==0 || p == NULL) return; Term *cur = p->first, *prev =NULL; while (cur != NULL && cur->expo > e) { prev = cur; cur = cur->link; } if (cur != NULL && cur->expo == e) { cur->coef += c; if(cur->coef == 0) { if (prev == NULL) p->first = cur->link; else prev->link = cur->link; p->size--; free(cur); } return; } Term *newTerm = createTerm(c, e); if (prev == NULL) p->first = newTerm; else { prev->link = newTerm; newTerm->link = cur; } p->size++; } 다항식에 항목 추가하기 -구현
  • 52. 다항식 출력하기 void polyPrint(Polynomial *poly) { Term *ptrTerm = poly->first; for (int i = 0; i < poly->size; i++) { printf("%dx^%d ", ptrTerm->coef, ptrTerm->expo); if (i != poly->size -1) printf(" + "); ptrTerm = ptrTerm->link; } printf("n"); }
  • 53. 다항식 삭제하기 void delPolynomial(Polynomial *poly) { Term *ptrTerm = poly->first, *cur; for (int i = 0; i < poly->size; i++) { cur = ptrTerm; ptrTerm = ptrTerm->link; free(cur); } free(poly); }
  • 54. 두 다항식 더하기다항식 더하기 Polynomial *addPoly(Polynomial *a, Polynomial *b) { Term *pa = a->first, *pb = b->first, *newTerm; int coef, expo; Polynomial *result = createPolynomial(“sum”); while (pa != NULL && pb != NULL) { if (pa->expo > pb->expo) { coef = pa->coef; expo = pa->expo; addTermtoPoly(coef, expo, result); pa = pa->link; } else if (pa->expo == pb->expo) { coef = pa->coef + pb->coef; expo = pa->expo; addTermtoPoly(coef, expo, result); pa = pa->link; pb = pb->link; } else { coef = pb->coef; expo = pb->expo; addTermtoPoly(coef, expo, result); pb = pb->link; } } while (pa != NULL){addTermtoPoly(pa->coef, pa->expo, result); pa = pa->link;} while (pb != NULL){addTermtoPoly(pb->coef, pb->expo, result); pb = pb->link;} return result; }
  • 56. #ifndef _Linked_List_ #define _Linked_List_ ListNode *createNode(int data, ListNode *link); void insertFirst(ListNode **ptrHead, int item); void insertAfterNode(ListNode *prev, int item); void insertNode(ListNode** phead, ListNode* p, ListNode* newNode); ListNode *removeFirst(ListNode **head); ListNode *removeAfter(ListNode **head, ListNode *prev); ListNode traverse(ListNode *head); ListNode *search(ListNode *head, int value); ListNode *concat(ListNode *head1, ListNode *head2); ListNode *reverse(ListNode *head); #endif Linked_List
  • 57. Linked_List: 추가되어야 할 요소 int isEmpty(ListNode *ptrHead); // List가 비어 있는지 확인 int getLength(ListNode *ptrHead); // List의 Node 수 확인 // List에서 pos에 있는 Node를 반환 ListNode *getNodeAt(ListNode *ptrHead, int pos); // List에서 pos에 있는 data를 반환 int getEntryAt(ListNode *ptrHead, int pos); // List에서 주어진 위치에 데이터 삽입 void insertNodeAt(ListNode **ptrHead, int pos, int item); // List의 마지막에 데이터 삽입 void insertLast(ListNode **ptrHead, int item); // List에서 주어진 위치의 데이터를 삭제 ListNode *removeAt(ListNode **ptrHead, int pos); // List의 모든 노드를 삭제 void removeAll(ListNode *ptrHead); // List의 모든 노드의 데이터 출력 void printData(ListNode *ptrHead);
  • 58. 연결 리스트 응용 - line editor -
  • 59. Line Editor Editor Command 창에서 한 줄씩 입력하거나 삭제 라인 번호와 라인의 내용을 입력받아 지정된 위치에 저장 각 라인에 해당하는 텍스트를 연결 리스트 노드의 데이터로 처리 커서를 사용하지 않는 단순한 에디터 파일을 이용하여 문서를 저장 및 편집 Line Editor
  • 60. 파일 읽고 쓰기 위한 기본 함수 파일을 열고 닫는 함수: fopen, fclose 파일로 부터 데이터를 읽는 함수: fscanf, fgets, fread 파일로 데이터를 쓰는 함수: fprintf, fputs Line Editor: fopen/fclose fopen() 함수 프로토타입: FILE* fopen(const char* filename, const char* mode); FILE: _iobuf라는 구조체 (입출력장치에 대한 관련 정보 저장) filename: 읽거나 쓰고자 하는 파일 이름 mode (파일 액세스 모드): r, w, a, r+, w+, a+, t , b fclose() 함수 프로토타입: int fclose(File* fprt); 반환 데이터: 파일이 오류없이 닫히면 0을 리턴 fopen() 함수로 파일을 열었으면 작업을 완료 후 반드시 fclose()함수로 닫아야 함 입력 파라미터: 파일포인터 입력 파라미터: 반환 데이터: 파일 포인터
  • 61. Line Editor / fgets() fgets() 함수 프로토타입: char* fgets(char *string, int n, FILE* stream); 반환 데이터: 읽은 문자열의 포인터, 더 읽을 내용이 없거나 에러 시 NULL 반환 입력 파라미터(3): 파일 데이터를 읽어 저장할 버퍼의 포인터 (string), 읽을 최대 문자 수 +1 (n), 오픈한 FILE 구조체 (_iobuf 구조체) 포인터 (stream) #include <stdio.h> int main(){ char buf[20]; char *line; FILE *fptr = fopen(“data.txt”,”r”); if(fptr == NULL) { // 에러 처리 } else { while ((line = fgets(buf, sizeof(buf), fptr)) != NULL) { printf(“%s”,line); } fclose(fptr); } return 0; } 파일에서 읽은 데이터 포인터 파일 끝이나 ‘n’ 문자까지 읽음 라인 끝(CR/LF)을 읽으면 개행 문자 ‘n’으로 변환 읽은 문자들 끝에 NULL 문자 추가 오픈한 파일에서 문자열을 한 줄씩 읽어옴
  • 62. Line Editor: fputs() fputs() 함수 프로토타입: int fputs(const char *string, FILE* stream); 반환 데이터: 성공 시 0 또는 양수, 실패 시 EOF(-1) 입력 파라미터(2): 파일에 쓸 NULL로 끝나는 문자열 버퍼의 포인터 (string), 오픈한 FILE 구조체 (_iobuf 구조체) 포인터 (stream) 개방된 파일에 문자열을 라인 단위로 저장 int main( ){ char buf[255]; FILE *fptr = fopen("data1.txt", "w"); int result; if(fptr == NULL) { // 에러 처리 코드 } else { for (int i = 0; i < 5; i++ ) { sprintf(buf, "[line:%d] %s n", i+1, in[i]); result = fputs(buf, fptr); if (result == -1) printf ("file write errorn"); } fclose(fptr); } } 쓰기 모드 파일에 저장될 문자 한 줄 개행 문자 ‘n’ 문자를 라인 끝(CR/LF)로 변환 파일 포인터