Chapter 04. 연결 리스트(Linked List) 2

Slides:



Advertisements
Similar presentations
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
Advertisements

ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
제14장 동적 메모리.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
연결리스트(linked list).
제 9 장 구조체와 공용체.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
컴퓨터 프로그래밍 기초 [Final] 기말고사
11장 구조체와 열거형 구조체의 정의 구조체 변수의 선언 구조체 초기화 및 사용 구조체 재정의 포인터를 이용해서 구조체 사용
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
P150 문제를 프로그래밍 할 것 Source file (헤더파일포함), 실행화면 (학번_이름_1.txt)
Dynamic Memory and Linked List
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
26. 매크로와 전처리기.
23장. 구조체와 사용자 정의 자료형 2.
자료구조: CHAP 4 리스트 (1) 순천향대학교 컴퓨터공학과 하 상 호.
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
프로그래밍 랩 – 7주 리스트.
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
Introduction To Data Structures Using C
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
자기참조 구조체(1) 먼저 자신과 같은 형의 구조체를 포인트하는 포인터 멤버 필드를 갖는 구조체를 정의한다.
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
자료구조: CHAP 7 트리 –review 순천향대학교 컴퓨터공학과 하 상 호.
27장. 모듈화 프로그래밍.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
Quiz #7 다음 수들을 합병 정렬과 퀵 정렬 알고리즘을 이용하여 오름 차순으로 정렬하였을 때, 데이터 이동 회수를 각각 구하라. 여러분은 정렬 과정을 단계별로 보이면서 이동 회수를 추적해야 한다. 단, 퀵 정렬시에 피봇으로 배열의 왼쪽 첫 번째 원소를 선택한다. 5.
24장. 파일 입출력.
* 프로그램을 간단히 하기 위해 malloc 성공체크는 안 함
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
C언어 응용 제7주 실습 해보기 제6장.
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
메모리 타입 분석을 통한 안전하고 효율적인 메모리 재사용
컴퓨터 계측 및 실습 디지털 출력 영남대학교 기계공학부.
Fucntion 요약.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
객체기반 SW설계 팀활동지 4.
^^ Computer Programming 2 dmpr.cnu.ac.kr/~daygax.
디버깅 관련 옵션 실습해보기 발표 : 2008년 5월 19일 2분반 정 훈 승
보고서 #2(제출기한: 09/23) 다음 문제를 해결하시오. (7)
DA :: 퀵 정렬 Quick Sort 퀵 정렬은 비교방식의 정렬 중 가장 빠른 정렬방법이다.
Homework #12 (1/2) 프로그램을 작성하고, 프로그램과 실행 결과를 프린트하여 제출한다.
7주차: Functions and Arrays
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
Chapter 10 데이터 검색1.
11장 배열 1. 배열이란? 1.1 배열의 개요 1.2 배열의 선언과 사용.
Summary of Pointers and Arrays
Numerical Analysis Programming using NRs
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 23. 구조체와 사용자 정의 자료형2.
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
엔코더 프로그램 설명 // 쓰레드를 사용하기 때문에 변수와 핸들을 전역변수로 지정 HANDLE hDevice;
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 05. 복사 생성자.
어서와 C언어는 처음이지 제21장.
13. 포인터와 배열! 함께 이해하기.
C++ Espresso 제15장 STL 알고리즘.
Pointers summary.
7 생성자 함수.
6 객체.
Presentation transcript:

Chapter 04. 연결 리스트(Linked List) 2 연결 리스트의 개념적인 이해

Linked! 무엇을 연결하겠다는 뜻인가! 일종의 바구니, 연결이 가능한 바구니 typedef struct _node { int data; // 데이터를 담을 공간 struct _node * next; // 연결의 도구! } Node; 일종의 바구니, 연결이 가능한 바구니 예제 LinkedRead.c의 분석을 시도 바랍니다!

예제 LinkedRead.c의 분석: 초기화 typedef struct _node { int data; struct _node * next; } Node; int main(void) Node * head = NULL; Node * tail = NULL; Node * cur = NULL; Node * newNode = NULL; int readData; . . . . } ∙ head, tail, cur이 연결 리스트의 핵심! ∙ head와 tail은 연결을 추가 및 유지하기 위한것 ∙ cur은 참조 및 조회를 위한것 LinkedRead.c의 일부

예제 LinkedRead.c의 분석: 삽입 1회전 while(1) { printf("자연수 입력: "); scanf("%d", &readData); if(readData < 1) break; // 노드의 추가과정 newNode = (Node*)malloc(sizeof(Node)); newNode->data = readData; newNode->next = NULL; if(head == NULL) head = newNode; else tail->next = newNode; tail = newNode; } LinkedRead.c의 일부

예제 LinkedRead.c의 분석: 삽입 2회전 while(1) { printf("자연수 입력: "); scanf("%d", &readData); if(readData < 1) break; // 노드의 추가과정 newNode = (Node*)malloc(sizeof(Node)); newNode->data = readData; newNode->next = NULL; if(head == NULL) head = newNode; else tail->next = newNode; tail = newNode; } 다수의 노드를 저장한 결과 LinkedRead.c의 일부

예제 LinkedRead.c의 분석: 데이터 조회 전체 데이터의 출력 과정 if(head == NULL) { printf("저장된 자연수가 존재하지 않습니다. \n"); } else cur = head; printf("%d ", cur->data); while(cur->next != NULL) cur = cur->next; LinkedRead.c의 일부

예제 LinkedRead.c의 분석: 데이터 삭제 전체 노드의 삭제 과정 if(head == NULL) { return 0; } else Node * delNode = head; Node * delNextNode = head->next; printf("%d을 삭제\n", head->data); free(delNode); while(delNextNode != NULL) delNode = delNextNode; delNextNode = delNextNode->next; printf("%d을 삭제\n", delNode->data); LinkedRead.c의 일부

Chapter 04. 연결 리스트(Linked List) 2 단순 연결 리스트의 ADT와 구현

정렬 기능 추가된 연결 리스트의 ADT1 이전과 동일 이전과 동일 이전과 동일 이전과 동일

정렬 기능 추가된 연결 리스트의 ADT2 이전과 동일 이전과 동일 새로 추가된 함수 SetSortRule 함수는 정렬의 기준을 설정하기 위해 정의된 함수! 이 함수의 선언 및 정의를 이해하기 위해서는 ‘함수 포인터’의 대한 이해가 필요하다.

새 노드의 추가 위치에 따른 장점과 단점 새 노드를 연결 리스트의 머리에 추가하는 경우 ∙ 장점 포인터 변수 tail이 불필요하다. ∙ 단점 저장된 순서를 유지하지 않는다. 새 노드를 연결 리스트의 꼬리에 추가하는 경우 ∙ 장점 저장된 순서가 유지된다. ∙ 단점 포인터 변수 tail이 필요하다. 두 가지 다 가능한 방법이다. 다만 tail의 관리를 생략하기 위해서 머리에 추가하는 것을 원칙으로 하자!

SetSortRule 함수 선언에 대한 이해 void SetSortRule ( List * plist, int (*comp)(LData d1, LData d2) ); √ 반환형이 int이고, int (*comp)(LData d1, LData d2) √ LData형 인자를 두 개 전달받는, int (*comp)(LData d1, LData d2) √ 함수의 주소 값을 전달해라! int (*comp)(LData d1, LData d2) int WhoIsPrecede(LData d1, LData d2) // typedef int LData; { if(d1 < d2) return 0; // d1이 정렬 순서상 앞선다. else return 1; // d2가 정렬 순서상 앞서거나 같다. } 인자로 전달이 가능한 함수의 예

정렬의 기준을 결정하는 함수에 대한 약속! 약속에 근거한 함수 정의의 예 Cr에 저장된 값이 0이라면 이렇듯 결정된 약속을 근거로 함수가 정의되어야 하며, 연결 리스트 또한 이를 근거로 구현되어야 한다. int WhoIsPrecede(LData d1, LData d2) { if(d1 < d2) return 0; // d1이 정렬 순서상 앞선다. else return 1; // d2가 정렬 순서상 앞서거나 같다. } 약속에 근거한 함수 정의의 예 int cr = WhoIsPrecede(D1, D2); Cr에 저장된 값이 0이라면 head . . . D1 . . D2 . . . tail D1이 head에 더 가깝다. Cr에 저장된 값이 1이라면 head . . . D2 . . D1 . . . tail D2가 head에 더 가깝다.

우리가 구현할 더미 노드 기반 연결 리스트 첫 번째 노드와 두 번째 이후의 노드 추가 및 삭제 방식이 다를 수 있다. 머리에 새 노드를 추가하되 더미 노드 없는 경우 첫 번째 노드와 두 번째 이후의 노드 추가 및 삭제 방식이 다를 수 있다. 머리에 새 노드를 추가하되 더미 노드 있는 경우 노드의 추가 및 삭제 방식이 항상 일정하다. LinkedRead.c와 문제 04-2의 답안인 DLinkedRead.c를 비교해보자!

정렬 기능 추가된 연결 리스트의 구조체 연결 리스트에 필요한 변수들을 구조체로 묶지 않는 것은 옳지 못하다. 노드의 구조체 표현 연결 리스트에 필요한 변수들을 구조체로 묶지 않는 것은 옳지 못하다. 연결 리스트의 구조체 표현

정렬 기능 추가된 연결 리스트 헤더파일 뒷부분 앞부분 #define TRUE 1 #define FALSE 0 typedef int LData; typedef struct _node { LData data; struct _node * next; } Node; typedef struct _linkedList Node * head; Node * cur; Node * before; int numOfData; int (*comp)(LData d1, LData d2); } LinkedList; typedef LinkedList List; void ListInit(List * plist); void LInsert(List * plist, LData data); int LFirst(List * plist, LData * pdata); int LNext(List * plist, LData * pdata); LData LRemove(List * plist); int LCount(List * plist); void SetSortRule(List * plist, int (*comp)(LData d1, LData d2)); 앞부분

더미 노드 연결 리스트 구현: 초기화 초기화 함수의 정의를 위해서 살펴봐야 하는 구조체의 정의 초기화 함수의 정의

더미 노드 연결 리스트 구현: 삽입1

더미 노드 연결 리스트 구현: 삽입2 모든 경우에 있어서 동일한 삽입과정을 거친다는 것이 더미 노드 기반 연결 리스트의 장점!

더미 노드 연결 리스트 구현: 참조1

더미 노드 연결 리스트 구현: 참조2

더미 노드 연결 리스트 구현: 삭제1 삭제 전 삭제 후 cur은 삭제 후 제조정의 과정을 거쳐야 하지만 before는 LFirst or LNext 호출 시 재설정되므로 재조정의 과정이 불필요하다.

더미 노드 연결 리스트 구현: 삭제2

Dlinkedlist.c DLinkedlist.h DLinkedlistmain.c 더미 기반 단순 연결 리스트 한데 묶기 실행결과 Dlinkedlist.c DLinkedlist.h DLinkedlistmain.c Chapter 03의 ListMain.c의 main 함수와 완전히 동일하다. 다만 노드를 머리에 추가하는 방식이기 때문에 실행결과에서는 차이가 난다.

Chapter 04. 연결 리스트(Linked List) 2 연결 리스트의 정렬 삽입의 구현

정렬기준 설정과 관련된 부분 단순 연결 리스트의 정렬 관련 요소 세 가지 하나의 문장으로 구성한 결과 ∙ 정렬기준이 되는 함수를 등록하는 SetSortRule 함수 ∙ SetSortRule 함수 통해 전달된 함수정보 저장을 위한 LinkedList의 멤버 comp ∙ comp에 등록된 정렬기준을 근거로 데이터를 저장하는 SInsert 함수 하나의 문장으로 구성한 결과 “SetSortRule 함수가 호출되면서 정렬의 기준이 리스트의 멤버 comp에 등록되면, SInsert 함수 내에서는 comp에 등록된 정렬의 기준을 근거로 데이터를 정렬하여 저장한다.”

SetSortRule 함수와 멤버 comp void SetSortRule(List * plist, int (*comp)(LData d1, LData d2)) { plist->comp = comp; } typedef struct _linkedList { Node * head; Node * cur; Node * before; int numOfData; int (*comp)(LData d1, LData d2); } LinkedList; 2. 멤버 comp가 초기화되면. . . . void LInsert(List * plist, LData data) { if(plist->comp == NULL) FInsert(plist, data); else SInsert(plist, data); } 3. 정렬 관련 SInsert 함수가 호출된다.

SInsert 함수1 위 상황에서 다음 문장이 실행되었다고 가정! SInsert(&slist, 5); void SInsert(List * plist, LData data) { Node * newNode = (Node*)malloc(sizeof(Node)); Node * pred = plist->head; newNode->data = data; // 새 노드가 들어갈 위치를 찾기 위한 반복문! while(pred->next != NULL && plist->comp(data, pred->next->data) != 0) pred = pred->next; // 다음 노드로 이동 } newNode->next = pred->next; pred->next = newNode; (plist->numOfData)++; 위 상황에서 다음 문장이 실행되었다고 가정! SInsert(&slist, 5);

SInsert 함수2 void SInsert(List * plist, LData data) { Node * newNode = (Node*)malloc(sizeof(Node)); Node * pred = plist->head; newNode->data = data; // 새 노드가 들어갈 위치를 찾기 위한 반복문! while(pred->next != NULL && plist->comp(data, pred->next->data) != 0) pred = pred->next; // 다음 노드로 이동 } newNode->next = pred->next; pred->next = newNode; (plist->numOfData)++; comp가 0을 반환한다는 것은 첫 번째 인자인 data가 정렬 순서상 앞서기 때문에 head에 가까워야 한다는 의미!

SInsert 함수3 void SInsert(List * plist, LData data) { Node * newNode = (Node*)malloc(sizeof(Node)); Node * pred = plist->head; newNode->data = data; // 새 노드가 들어갈 위치를 찾기 위한 반복문! while(pred->next != NULL && plist->comp(data, pred->next->data) != 0) pred = pred->next; // 다음 노드로 이동 } newNode->next = pred->next; pred->next = newNode; (plist->numOfData)++;

정렬의 핵심인 while 반복문 ∙ 반복의 조건 1 pred->next != NULL ∙ 반복의 조건 2 plist->comp(data, pred->next->data) != 0 새 데이터와 pred의 다음 노드에 저장된 데이터의 우선순위 비교를 위한 함수호출 while(pred->next != NULL && plist->comp(data, pred->next->data) != 0) { pred = pred->next; // 다음 노드로 이동 }

comp의 반환 값과 그 의미 우리의 결정 내용! 이 내용을 근거로 SInsert 함수를 정의하였다. ∙ comp가 0을 반환 while(pred->next != NULL && plist->comp(data, pred->next->data) != 0) { pred = pred->next; // 다음 노드로 이동 } 우리의 결정 내용! 이 내용을 근거로 SInsert 함수를 정의하였다. ∙ comp가 0을 반환 첫 번째 인자인 data가 정렬 순서상 앞서서 head에 더 가까워야 하는 경우 ∙ comp가 1을 반환 두 번째 인자인 pred->next->data가 정렬 순서상 앞서서 head에 더 가까워야 하는 경우

정렬의 기준을 설정하기 위한 함수의 정의 Dlinkedlist.c DLinkedlist.h ∙ 두 개의 인자를 전달받도록 함수를 정의한다. ∙ 첫 번째 인자의 정렬 우선순위가 높으면 0을, 그렇지 않으면 1을 반환한다. 함수의 정의 기준 int WhoIsPrecede(int d1, int d2) { if(d1 < d2) return 0; // d1이 정렬 순서상 앞선다. else return 1; // d2가 정렬 순서상 앞서거나 같다. } 오름차순 정렬을 위한 함수의 정의 정렬 관련된 함수를 DLinkedListSortMain.c에 포함시켜야 함을 이해한다. Dlinkedlist.c DLinkedlist.h DLinkedlistSortmain.c 실행결과