5장. 리스트 리스트 학습목표 목록이나 도표처럼 여러 데이터를 관리할 수 있는 자료형을 추상화

Slides:



Advertisements
Similar presentations
스택 스택 추상자료형 스택 스택의 구현 스택의 응용 한빛미디어(주).
Advertisements

Vision System Lab, Sang-Hun Han
C++ Espresso 제1장 기초 사항.
3 장 stack and queue.
Internet Computing KUT Youn-Hee Han
제 8 장  파서 생성기 YACC 사용하기.
실전 프로젝트 2 : 숫자야구 숫자 야구를 구현해보자.
CHAP 6:큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
8. 객체와 클래스 (기본).
Internet Computing KUT Youn-Hee Han
Internet Computing KUT Youn-Hee Han
C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
4장 스택.
CHAP 7:트리.
강의 #7 트리(Tree).
7 스택.
배열, 포인터, 참조 배열은 같은 형을 가지는 변수들의 묶음이다..
Chapter 5. General Linear List
제 4 장 L i s t.
스택(stack) SANGJI University Kwangman Ko
head data link data link data link NULL a b c
HW#2 #1과 동일한 방법으로 argc와 argv를 사용함
강의 #6 큐(Queue).
CHAP 6:큐 C로 쉽게 풀어쓴 자료구조 Slide 1 (of 27).
CHAP 6:큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
다음 주 과제 7장 읽어오기 숙제 해서 다음 주(11월 12일) 제출하기. 큐(Queue) E304호,
Chapter 9 – 구조형과 리스트 처리 Outline 9.1 자신 참조 구조형 9.2 선형 연결 리스트 9.3 리스트 연산
자료구조: CHAP 4 리스트 (2) 순천향대학교 컴퓨터공학과 하 상 호.
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 03. 클래스의 기본.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
C언어 응용 제 10 주 트리.
Data structures 01.2: C++ classes 동의대학교 멀티미디어공학과 이광의교수.
14장. 함수 1 01_ 함수의 기본 02_ 인자의 전달.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
C++ 개요 객체지향 윈도우즈 프로그래밍 한국성서대학교 유일선
스택(Stack) 김진수
프로그래밍 랩 – 7주 리스트.
CHAP 8:우선순위큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2011.
Tree & Heap SANGJI University Kwangman Ko
CHAP 7:트리 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
Chapter 3 클래스. 최호성.
추상 데이터 타입 정의하기 Defining abstract data types
8 큐.
배열과 연결리스트 연결리스트 배열 메모리 할당이 연속적이어서 인덱스 사용시 검색이 빠르다.
CHAP 7:트리 C로 쉽게 풀어쓴 자료구조 생능출판사 2005.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
Chapter 04 리스트.
제 12장. 사용자 정의형으로서의 클래스 학기 프로그래밍언어및실습 (C++).
자료구조: CHAP 4 리스트 (2) 순천향대학교 컴퓨터공학과 하 상 호.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Lecture 8 복잡한 구조 프로그래밍 프로그램 짤 때의 마음가짐 invariant 데이터 구성 list pair
자료구조: CHAP 7(2) 트리 순천향대학교 컴퓨터공학과 하 상 호.
조 병 규 Software Quality Lab. 한 국 교 통 대 학 교
Lecture 7 복잡한 구조 프로그래밍 프로그램 짤 때의 마음가짐 invariant list set
CHAP 8:우선순위큐.
조 병 규 Software Quality Lab. 한 국 교 통 대 학 교
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
Chapter 07 트리.
C++ 언어의 특징
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 02. C언어 기반의 C++ 2.
프로그래밍 기법 최적화 프로그래밍.
Presentation transcript:

5장. 리스트 리스트 학습목표 목록이나 도표처럼 여러 데이터를 관리할 수 있는 자료형을 추상화 데이터 삽입, 삭제, 검색 등 필요 작업을 가함 스택과 큐는 리스트의 특수한 경우에 해당 학습목표 추상 자료형 리스트 개념과 필요 작업을 이해한다. 배열로 구현하는 방법, 연결 리스트로 구현하는 방법을 숙지한다. C로 구현할 때와 C++로 구현할 때의 차이점을 이해한다. 자료구조로서 배열과 연결 리스트의 장단점을 이해한다.

목록( 도표) Position Name Quantity 1 Beer 10 2 Gum 5 3 Apple 4 Potato 8 Onion ...

추상 자료형 리스트의 작업 Insert(Position, Data) Delete(Position) Retrieve(Position, Data)  해당 위치(Position)의 데이터를 Data 변수에 복사 Create( )                빈 리스트 만들기 (종이 준비) Destroy( )              리스트 없애기(종이 버리기) IsEmpty( )              빈 리스트인지 확인 (아무 것도 안 적혔는지 확인) Length( )               몇 개의 항목인지 계산 (몇 개나 적혔는지 세기)

공리 공리 리스트 공리 Insert(1, Ramen) 추상자료형의 작업을 형식화 (aList.Create( )).Length( ) = 0 (aList.Insert(i, Data)).Length( ) = aList.Length( ) + 1 (aList.Create( )).IsEmpty( ) = TRUE (aList.Insert(i, Data)).Delete(i) = aList (aList.Create( )).Delete(i) = ERROR Insert(1, Ramen) 밀릴 것인가, 지울 것인가 공리로도 명시하기 어려움 인터페이스 파일에 정확한 커멘트를 요함

C 배열에 의한 리스트 구조체 카운트 변수 데이터 배열 Count Data[ ] 2 1 ... (MAX-1) 324 256  

C 배열에 의한 리스트 코드 5-1: ListA.h (C Interface by Array) #define MAX 100                               최대 100개 데이터를 저장 typedef struct           { int Count;                                     리스트 길이(데이터 개수)를 추적   int Data[MAX];                        리스트 데이터는 정수형 } listType;                                      리스트 타입은 구조체 void Insert(listType *Lptr, int Position, int Item):   해당위치에 데이터를 삽입 void Delete(listType *Lptr, int Position);               해당위치 데이터를 삭제 void Retrieve(listType *Lptr, int Position, int *ItemPtr);  찾은 데이터를 *ItemPtr에 넣음 void Init(listType *Lptr);                        초기화   bool IsEmpty(listType *Lptr);                    비어있는지 확인  int Length(listType *Lptr);                      리스트 내 데이터 개수

C 배열에 의한 리스트 void Insert(listType *Lptr, int Position, int Item): 자료구조를 함수호출의 파라미터로 전달 리스트를 가리키는 포인터를 Lptr로 복사해 달라는 것 C 언어로 구현할 때 일반특성으로서 전역변수를 회피하기 위함 삽입, 삭제는 원본 자체를 바꾸는 작업이므로 참조호출이 필요 리스트 자체 데이터는 복사되지 않음. 복사에 따른 시간도 줄어든다. void Retrieve(listType *Lptr, int Position, int *ItemPtr);  호출함수의 원본 데이터를 가리키는 포인터 값을 ItemPtr로 *ItemPtr를 변형하면 호출함수의 원본 데이터 값이 변함 void main( ) { listType List1;   int Result;   Insert(&List1, 1, 23);     리스트 처음에 23을 넣기   Retrieve(&List1, 1, &Result); 리스트의 첫 데이터를 Result에 넣기 }

C 배열에 의한 리스트 코드 5-2: ListA.c (C Implementation by Array) #include <ListA.h>                              헤더파일을 포함 void Init(listType *Lptr)                     초기화 루틴 { Lptr->Count = 0;                             데이터 수를 0으로 세팅 } bool IsEmpty(listType *Lptr)              비어있는지 확인하는 함수 { return (Lptr->Count = = 0);              빈 리스트라면 TRUE             void Insert(listType *Lptr, int Position, int Item)     삽입함수 { if (Lptr->Count = = MAX)                   현재 꽉 찬 리스트        printf("List Full");            else if ((Position > (Lptr->Count+1)) || (Position < 1))         printf("Position out of Range");   이격된 삽입위치 불허   else   { for (int i = (Lptr->Count-1); i >= (Position-1); i--) 끝에서부터 삽입위치까지          Lptr->Data[i+1] = Lptr->Data[i];    오른쪽으로 한 칸씩 이동     Lptr->Data[Position-1] = Item;           원하는 위치에 삽입      Lptr->Count += 1;                                  리스트 길이 늘림   }

연결 리스트 기초 typedef struct { int Data; 노드 내부의 실제 데이터 또는 레코드   node* Next;      Next가 가리키는 것은 node 타입 } node;                  구조체에 node라는 새로운 타입명 부여 typedef node* Nptr;    Nptr 타입이 가리키는 것은 node 타입 Nptr p, q;               Nptr 타입 변수 p, q를 선언

연결 리스트 연결 리스트 개념

연결 리스트 기초 노드 만들기, 이어 붙이기 p = (node *)malloc(sizeof(node)); p->Data = 33;                    p->Next = (node *)malloc(sizeof(node)); p->Next->Data = 22; p->Next->Next = NULL;

연결 리스트 기초 공간반납 Nptr Head; Head = (node *)malloc(sizeof(node)); Head -> Data = 11; Head -> Next = NULL Head = NULL;

연결 리스트 기본조작 디스플레이 Temp = Head; While (Temp != NULL)   {    printf("%d ", Temp->Data);       Temp = Temp->Next;   }

연결 리스트 기본조작 간단한 삽입 p = (node *)malloc(sizeof(node)); p->Data = 8; p->Next = Temp->Next;                     Temp->Next = p;

연결 리스트 기본조작 간단한 삭제 p = Temp->Next; Temp->Next = Temp->Next->Next; free p;

C 연결 리스트에 의한 리스트 C 연결 리스트에 의한 리스트

C 연결 리스트에 의한 리스트 코드 5-3: ListP.h (C Interface by Linked List) typedef struct { int Data;           노드 내부의 실제 데이터 또는 레코드   node* Next;     Next가 가리키는 것은 node 타입, 즉 자기 자신 타입 } node;                 구조체에 node라는 새로운 타입명 부여 typedef node* Nptr;    Nptr 타입이 가리키는 것은 node 타입 { int Count;      리스트 길이를 추적   Nptr Head;      헤드 포인터로 리스트 전체를 대변함 } listType; void Insert(listType *Lptr, int Position, int Item):  해당위치에 데이터를 삽입 void Delete(listType *Lptr, int Position);                해당위치 데이터를 삭제 void Retrieve(listType *Lptr, int Position, int *ItemPtr);  void Init(listType *Lptr);                                초기화   bool IsEmpty(listType *Lptr);                            비어있는지 확인  int Length(listType *Lptr);                              리스트 내 데이터 수

C 연결 리스트에 의한 리스트 코드 5-4: ListP.c (C Implementation by Linked List) #include <ListP.h>                     헤더파일을 포함 void Init(listType *Lptr) { Lptr->Count = 0;                     리스트 길이를 0으로 초기화   Head = NULL;                        헤드 포인터를 널로 초기화 }                bool IsEmpty(listType *Lptr)           빈 리스트인지 확인하기 { return (Lptr->Count = = 0);           리스트 길이가 0이면 빈 리스트 }

C 연결 리스트에 의한 리스트 코드 5-4: ListP.c (C Implementation by Linked List) void Insert(listType *Lptr, int Position, int Item) 삽입함수 { if ((Position > (Lptr->Count+1)) || (Position < 1))       printf("Position out of Range");    이격된 삽입위치 불허   else   {   Nptr p = (node *)malloc(sizeof(node)); 삽입될 노드의 공간 확보                    p->Data = Item;                  데이터 값 복사      if (Position = = 1)                첫 위치에 삽입할 경우      {    p->Next = Lptr->Head;      삽입노드가 현재 첫 노드를 가리킴            Lptr->Head = p;             헤드가 삽입노드를 가리키게       }     else                               첫 위치가 아닐 경우       {    Nptr Temp = Lptr->Head;   헤드 포인터를 Temp로 복사          for (int i = 1; i < (Position-1); i++)                Temp = Temp->Next;   Temp가 삽입직전 노드를 가리키게            p->Next = Temp->Next;     삽입노드의 Next를 세팅            Temp->Next = p;            직전노드가 삽입된 노드를 가리키게        }        Lptr->Count += 1;               리스트 길이 늘림    } }

배열과 연결리스트 비교(삽입) 연결 리스트 공간이 꽉 차 있는지 테스트할 필요가 없음 얼마든지 동적으로 새로운 노드를 추가 가능 중간위치 삽입에 따른 밀림(Shift)이 불필요 삽입직전 노드를 찾아가는 작업이 배열에 비해 오래 걸림 배열: 직접 접근 연결 리스트: 포인터를 따라서 리스트 순회

C 연결 리스트에 의한 리스트 코드 5-5: 위치기반 연결 리스트의 삭제 void Delete(listType *Lptr, int Position) 삭제함수 { if (IsEmpty(Lptr))       printf("Deletion on Empty List");         빈 리스트에서 삭제요구는 오류   else if (Position > (Lptr->Count) || (Position < 1))       printf("Position out of Range");            삭제 위치가 현재 데이터 범위를 벗어남   else   {    if (Position = = 1)                       첫 노드를 삭제하는 경우        {   Nptr p = Lptr->Head;                 삭제될 노드를 가리키는 포인터를 백업             Lptr->Head = Lptr->Head->Next;   헤드가 둘째 노드를 가리키게        }        else        {   for (int i = 1; i < (Position-1); i++)               Temp = Temp->Next;   Temp가 삭제직전 노드를 가리키게            Nptr p = Temp->Next;               삭제될 노드를 가리키는 포인터를 백업            Temp->Next = p->Next;             직전노드가 삭제될 노드 다음을 가리키게       }       Lptr->Count -= 1;                        리스트 길이 줄임       free (p);                                  메모리 공간 반납   } }

C 연결 리스트에 의한 리스트 값 기반 연결리스트의 삭제 Temp = Lptr->Head; while((Temp != NULL) && (Temp->Data != Item)     Temp = Temp->Next; 이 코드로는 템프가 삭제 직전에 놓이게 할 수 없음

C 연결 리스트에 의한 리스트 예견방식 데이터 15인 노드 삭제 Temp = Lptr->Head; while((Temp != NULL) && (Temp->Next->Data != Item)      Temp = Temp->Next; 데이터 15인 노드 삭제 Temp가 데이터 12인 노드를 가리킬 때, Temp는 널이 아니지만 Temp->Next는 널임.

C 연결 리스트에 의한 리스트 코드 5-6 정렬된 연결 리스트의 삭제 Delete(listType *Lptr, int Item) 삭제함수 {   Nptr Prev = NULL;                         Prev는 널로 초기화     Nptr Temp = Lptr->Head;                  Temp는 헤드로 초기화   while((Temp != NULL) && (Temp->Data != Item)     {    Prev = Temp;                          Prev가 Temp를 가리키게          Temp = Temp->Next;                  Temp는 다음 노드로 전진     }   if (Prev = = NULL)                          Temp가 한번도 전진하지 않았음   {    if (Temp = = NULL)                   처음부터 빈 리스트              printf("No Nodes to Delete");         else                                   삭제 대상이 첫 노드          {    Lptr->Head = Lptr->Head->Next;               free (Temp);   Lptr->Count - = 1;          }   else                                         Temp가 전진했음   {    if (Temp = = NULL)                   리스트 끝까지 삭제대상이 없음               printf("No Such Nodes");        else                                    삭제대상이 내부에 있음          {    Prev->Next = Temp -> Next;    직전노드가 삭제될 다음 노드를 가리킴               free (Temp);    Lptr->Count - = 1;                      }   }

이중연결 리스트 typedef struct { int Data;   node* Prev, Next;    Prev는 이전 노드를, Next는 다음 노드를 가리킴 } node; 

이중연결 리스트 단순연결 리스트의 삽입 테일 포인터가 따로 있으면 유리 삭제일 경우에는 테일 포인터가 뒤로 이동. 이중 연결 이어야 테일 포인터를 뒤로 이동할 수 있음.

원형 연결, 원형 이중연결 원형 연결 타임 셰어링 시스템의 타임 슬라이스 사용자 교대 원형 이중 연결

C 배열과 C++배열 비교 ListA.h (C++ Interface by Array) const int MAX = 100;                  #define MAX 100   class listClass { public:     listClass( );                         void Init(listType *Lptr);       listClass(const listClass& L);            ~listClass( );                             void Insert(int Position, int Item);    void Insert(listType *Lptr, int Position, int Item)     void Delete(int Position);    void Delete(listType *Lptr, int Position);      void Retrieve(int Position, int & Item);    void Retrieve(listType *Lptr, int Position, int *ItemPtr);     bool IsEmpty( );    bool IsEmpty(listType *Lptr);     int Length( );     int Length(listType *Lptr);          private:                               typedef struct     int Count;    { int Count;     int Data[MAX];      int Data[MAX]; }    } listType;

C++ 배열에 의한 리스트 코드 5-7: ListA.cpp (C++ Implementation by Array) #include <ListA.h> listClass::listClass( )                     생성자 { Count = 0;                            리스트 길이를 0으로 초기화 } listClass::~listClass( )                   소멸자 {                                listClass::listClass(const listClass& L)  복사 생성자 { Count = L.Count;                      리스트 길이를 복사   for (int i = 1; i <= L.Count; ++i)     깊은 복사에 의해 배열 요소 모두를 복사        Data[i-1] = L.Data[i-1];

C++ 연결 리스트에 의한 리스트 코드 5-8: ListP.h (C++ Interface by Linked List) typedef struct { int Data;                node* Next;           } node;                  typedef node* Nptr;     class listClass { public:     listClass( );                              listClass(const listClass& L);             ~listClass( );                             void Insert(int Position, int Item);        void Delete(int Position);     void Retrieve(int Position, int& Item);     bool IsEmpty( );     int Length( );    private:                                   int Count;     Nptr Head; }

C++ 연결 리스트에 의한 리스트 코드 5-9: ListP.cpp (C++ Implementation by Linked List) #include <ListP.h> listClass::listClass( )                     생성자 함수 { Count = 0;                            리스트의 길이를 0으로 초기화   Head = NULL;                        헤드를 널로 초기화 } bool listClass::IsEmpty( )                빈 리스트인지 확인하는 함수 { return (Count = = 0);                 배열 길이 0이면 TRUE

C++ 연결 리스트에 의한 리스트 코드 5-9: ListP.cpp (C++ Implementation by Linked List) void listClass::Delete(int Position)      삭제함수 { Nptr Temp;   if (IsEmpty( ))         cout << "Deletion on Empty List";빈 리스트에 삭제요구는 오류   else if ((Position > Count) || (Position < 1))         cout << "Position out of Range"; 삭제위치가 현재 데이터 범위를 벗어남   else   {    if (Position = = 1)               삭제될 노드가 첫 노드일 경우         {    Nptr p = Head;             삭제될 노드를 가리키는 포인터를 백업              Head = Head->Next;        헤드가 둘째 노드를 가리키게         }         else                              삭제노드가 첫 노드가 아닌 경우         {    for (int i = 1; i < (Position-1); i++)                 Temp = Temp->Next;   Temp가 삭제될 노드 직전노드로 이동              Nptr p = Temp->Next;      삭제될 노드를 가리키는 포인터를 백업              Temp->Next = p->Next;    직전노드가 삭제될 노드 다음을 가리키게       }        Count - = 1;                      리스트 길이 줄임        delete (p);                        메모리 공간 반납   } }

C++ 연결 리스트에 의한 리스트 코드 5-9: ListP.cpp (C++ Implementation by Linked List) listClass::~listClass( )                   소멸자 함수 { while (!IsEmpty( ))                    리스트가 완전히 빌 때까지        Delete(1);                          첫 번째 것을 계속 지우기 } listClass:ListClass(const listClass& L) 복사 생성자 함수 { Count = L.Count;                      일단 리스트 개수를 동일하게   if (L.Head = = NULL)        Head = NULL                    넘어온 게 빈 리스트라면 자신도 빈 리스트   else   {   Head = new node;         빈 리스트 아니라면 일단 새 노드를 만들고        Head->Data = L.Head->Data;     데이터 복사        Nptr Temp1 = Head;              Temp1은 사본을 순회하는 포인터       for (Nptr Temp2=L.Head->Next; Temp2 != NULL; Temp2=Temp2->Next)       {    Temp1->Next = new node;  사본의 현재 노드에 새 노드를 붙임             Temp1 = Temp1 -> Next;   새 노드로 이동             Temp1->Data = Temp2->Data; 새 노드에 원본 데이터를 복사         }        Temp1->Next = NULL;           사본의 마지막 노드의 Next에 널을 기입    }

배열과 연결 리스트의 비교 공간 검색시간 삽입, 삭제 시간 어떤 자료구조? 배열은 정적이므로 최대크기를 미리 예상해야 함. 만들어 놓은 배열 공간이 실제로 쓰이지 않으면 낭비 연결 리스트는 실행 시 필요에 따라 새로운 노드 생성 연결 리스트는 포인터 변수공간을 요함 검색시간 배열은 단번에 찾아감(묵시적 어드레싱: 인덱스 연산) 연결 리스트는 헤드부터 포인터를 따라감(현시적 어드레싱: 포인터 읽음) 삽입, 삭제 시간 배열의 삽입: 오른쪽 밀림(Shift Right) 배열의 삭제: 왼쪽 밀림(Shift Left) 연결 리스트: 인접 노드의 포인터만 변경 어떤 자료구조? 검색위주이면 배열이 유리 삽입 삭제 위주라면 연결 리스트가 유리 최대 데이터 수가 예측 불가라면 연결 리스트