Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Data Structure: Implementation and Analysis of Unsorted List using Array, Lecture notes of Algorithms and Programming

The implementation and analysis of an unsorted list using an array data structure. It covers the concepts of lists, their properties, and the differences between sorted and unsorted lists. The document also presents the algorithms for searching, inserting, and deleting elements in an unsorted list, along with their time complexities. Big-o notation is used to analyze the performance of these algorithms.

Typology: Lecture notes

2017/2018

Uploaded on 10/23/2018

keehwan
keehwan 🇨🇦

20 documents

1 / 13

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
- 51 -
제5장 리스트
장에서는 배열을 이용하여 리스트 자료구조를 구현하는 방법을 살펴본다.
5.1. 교육목표
장의 교육목표는 다음과 같다.
교육목표
리스트
비정렬 리스트
정렬 리스트
알고리즘 비교
Big-O 표기법
5.2. 리스트
리스트
리스트의 특성
동질
동질 구조
구조: 구조에 있는 모든 요소는 같은 타입이다.
요소들간에
요소들간에 선형
선형 관계가
관계가 존재
존재한다.
번째 요소를 제외한 모든 요소는 선행 요소가 있으며,
마지막 요소를 제외한 모든 요소는 후속 요소가 있다.
리스트에 있는 요소의 개수를 리스트의 크기라 한다.
리스트는 정렬되어 유지될 있고, 그렇지 않을 있다.
비정렬(unsorted) 리스트, 정렬(sorted) 리스트
정렬 리스트에서 요소가 복합 타입일 경우에는 정렬의 기준이 되는
키가 존재한다.
4.1)
4.1) 학생 기록부: 학번, 학생 이름, 나이, ...
Æ키는 다양하게 결정될 있다.
리스트는 다음과 같은 특성을 갖는 자료구조이다. 첫째, 동질 구조이다. 둘째, 요소들 간에
선형 관계가 존재한다. 선형 관계란 번째 요소를 제외하고는 모두 선행 요소가 있으며,
마지막 요소를 제외하고는 모두 후속 요소를 가진다는 것을 의미한다. 리스트는 요소를
기준에 따라 정렬하여 유지할 있고, 그렇지 않을 있다. 정렬 리스트의 경우에
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Partial preview of the text

Download Data Structure: Implementation and Analysis of Unsorted List using Array and more Lecture notes Algorithms and Programming in PDF only on Docsity!

리스트 비정렬 리스트 정렬 리스트 알고리즘 비교 Big-O 표기법

리스트의 특성 동질동질 구조구조 :^ 구조에 있는 모든 요소는 같은 타입이다. 요소들간에요소들간에 선형선형 관계가관계가 존재존재한다. 첫 번째 요소를 제외한 모든 요소는 선행 요소가 있으며 , 마지막 요소를 제외한 모든 요소는 후속 요소가 있다. 리스트에 있는 요소의 개수를 리스트의 크기라 한다. 리스트는 정렬되어 유지될 수 있고 , 그렇지 않을 수 있다. 비정렬 (unsorted) 리스트 , 정렬 (sorted) 리스트 정렬 리스트에서 요소가 복합 타입일 경우에는 정렬의 기준이 되는 키가 존재한다. 예예 4.1)4.1) 학생 기록부 : 학번 , 학생 이름 , 나이 , ... Æ 키는 다양하게 결정될 수 있다.

리스트 ADT 구현시 고려사항

중복 허용 여부 동일한 것이 여러 번 삽입될 수 있는지 여부 : 응용에 의해 결정 제공해야 하는 연산의 형태 보통 자료구조는 삽입 , 삭제 , 검색 , 추출 연산을 제공한다. 각 연산의 형태는 정해져 있지 않으며 , 응용에 따라 다를 수 있다. 예예 4.2)4.2)^ 삭제 주어진 키 값을 가진 요소를 삭제 자료구조 내에 특정 위치에 저장된 요소를 삭제

리스트 ADT를 구현할 때 먼저 몇 가지 고려해야 하는 사항이 있다. 첫째, 중복 요소를 허

5.3. UnsortedList

요소와 비교하였지만 같은 요소가 없는 경우에 완료한다. 따라서 search 연산은 이 두 가지 조건을 각각 나타내는 found와 moreToSearch 지역변수와 while 루프를 이용하여 구현할 수 있다. 이 방법 외에 우리는 배열에 저장되어 있는 요소의 개수를 size라는 멤버변수에 유지 하므로 size와 for 문을 이용하여 보다 간편하게 search 연산을 구현할 수도 있다. retrieve 연산은 search 연산과 반환하는 값만 다를 뿐 동일한 연산이다. retrieve은 주어진 키 값과 같은 요소를 찾아 그 요소를 반환하여 주며, 추출하고자 하는 요소가 없는 경우에는 null 값 을 반환한다.

boolean insert(Object item)

boolean insert(Object item){ if(item==null || isFull()) return false; elements[size] = item; // Listable x = (Listable)item; // elements[size] = x.clone(); size++; return true; }

item

elements

item elements

사전조건 : item!=null, 사후조건^ 리스트가 :^ 주어진 full 이 아님 item 을 리스트에 끝에 추가한다. 추가에 성공하면 못하면 false 를 반환한다 true,.

비정렬 리스트에서 삽입 연산은 요소를 특정 위치에 삽입할 필요가 없으므로 ArrayList처럼 리스트 맨 끝에 삽입하는 것이 비용측면에서 가장 저렴하다. 리스트 맨 끝 색인은 현재 리 스트의 크기 정보로부터 쉽게 얻을 수 있다. 배열을 이용한 리스트의 구현에서는 앞서 언급 한 바와 같이 리스트가 꽉 차있으면 더 이상 새 요소를 삽입하지 못한다. 이 장에서는 또한 참조 방식으로 구현하고 있으므로 주어진 새 요소를 복제하지 않고 참조를 배열에 저장한 다. 만약 복사 방식으로 이 구현을 변경하고자 하면 주석처리된 것처럼 주어진 인자를 Listable 타입으로 변환하여 복제한 것을 저장해야 한다.

boolean delete(Object item)

A D C F E A D E F

삭제할 것

boolean delete(Object item){ int loc = 0;boolean moreToSearch = (item!=null)&&(loc<size); while(moreToSearch){ if(item.equals(element[loc])){if(loc!=size-1) elements[loc] = elements[size-1]; size--; } return true; else{ } loc++; moreToSearch = (loc<size); } // while } // deletereturn false;

사전조건사전조건 : item!=null 사후조건사후조건있으면 그 : item item 이 리스트에을 삭제한다. 삭제에 성공하면 true 를 못하면 false 를 반환한다. 검색할 때 종료조건은 search 연산과 같음. 하지만 이 경우에는 두 개의 boolean 변수를 사용하지 않음.

정렬되어 있지 않는 리스트이므로 가능

순하게 그 항에 null 값을 대입한다고 삭제되는 것은 아니다. 배열을 이용한 리스트 구현에 서는 중간에 빈항이 없어야 한다. 이렇게 하지 않으면 삽입, 검색 등 다른 연산에 나쁜 영 향을 준다. 중간에 빈항이 없도록 요소를 삭제하기 위해 삭제하고자 하는 요소의 모든 후속 요소들을 하나씩 이동하는 방법을 생각할 수 있다. 하지만 리스트가 정렬되어 유지되는 것 이 아니므로 맨 끝 요소를 삭제하는 요소와 대체함으로 저렴하게 삭제할 수 있다. 검색할 때 종료하는 조건은 앞서 살펴본 insert와 같다. 하지만 두 개의 변수를 사용하지 않고, 하나 의 변수만을 이용하여 delete를 구현하고 있다. 이처럼 한 가지 방법으로만 메소드를 구현할 수 있는 것은 아니다.

boolean delete(Object item) – 계속

boolean delete(Object item){ if(item==null) return false;for(int loc = 0; loc<size; loc++) if(item.equals(element[loc])){ if(loc!=size-1) elements[loc] = elements[size-1];size--; return true; return false;} }

이 슬라이드에서는 boolean 변수를 전혀 사용하지 않고 for문을 이용하여 보다 간편하게 구 현하고 있다.

SortedList ADT – 계속

방법방법 2.2. abstract 클래스 사용 List 라는 클래스를 만들고 , UnsortedListSortedList 모두 List 의 자식 클래스로 만든다. 이 경우 두 클래스의 공통된 코드는 List 에 한번 정의하여 사용할 수 있다. 하지만 search, insert, delete 메소드는 두 클래스의 경우 달라야 하므로 List 에서 제공할 수 없다. Æ 추상 클래스 방법방법 3.3. 인터페이스 사용 인터페이스는 코드의 재사용은 아니다. 사용자에게 두 클래스가 공통된 메소드를 제공한다는 것을 알려주는 역할밖에 없음 UnsortedListSortedListList 클래스 외에 다른 클래스를 상속받아야 하면 인터페이스가 유일한 대안

둘째, 추상 클래스를 사용하는 것이다. 즉, List라는 추상 클래스를 만들고, UnsortedList와 SortedList가 모두 List의 자식 클래스가 되도록 만드는 것이다. 이 경우 두 클래스의 공통된 코드는 List 클래스에 한번만 정의하면 된다. 예를 들어 isFull, isEmpty, size 메소드 등은 정렬 리스트나 비정렬 리스트나 같으므로 이들은 List 클래스에 정의한다. 셋째, 인터페이스 를 사용하는 것이다. 하지만 인터페이스는 코드를 재사용하는 것이 아니므로 이 경우에는 두 번째 방법이 가장 바람직하다.

public abstract class List{ public final int DEF_CAPACITY=50; protected Object[] elements;protected int size = 0; protected int cursor = -1; public List(){ … }public List(int capacity){ … } private void setup(int capacity){ … } public boolean isFull(){ return (size >= element.length); } public int size(){ return size; }public boolean isEmpty(){ return (size == 0); } public abstract boolean search(Object item); public abstract boolean insert(Object item);public abstract boolean delete(Object item); public abstract Object retrieve(Object item); public void reset(){ cursor = 0; }public boolean hasNext(){ return cursor<size; } public Object next(){int loc = cursor; cursor++; } return element[loc]; } // List

public List(){ } setup(DEF_CAPACITY); public List(int capacity){ if(capacity>0) setup(capacity); } else setup(DEF_CAPACITY); private void setup(int capacity){ } elements = new Object[capacity];

List 추상 클래스는 위 슬라이드와 같이 정의할 수 있다.

SortedList ADT

public class SortedList extends List{public SortedList(){ super(); } public SortedList(int capacity){ super(capacity); } public boolean search(Object item){ … } public boolean insert(Object item){ … }public boolean delete(Object item){ … } public Object retrieve(Object item){ … } } // SortedList

List 추상 클래스를 상속받아 구현한 SortedList 클래스는 위 슬라이드와 같다.

boolean insert(Object item)

사전조건 : item!=null, 사후조건 :^ 리스트가리스트가 계속 정렬되어^ full 이 아님 있도록 주어진 item 을 추가한다. 추가에 성공하면 false 를 반환한다 true., 못하면 방법 1.2. 삽입할 위치를 찾는다삽입할 공간을 만든다 ..

3. 새 요소를 리스트에 삽입한다. 이 때 맨 앞에 , 중간에 , 끝에 삽입되는 경우를 고려해야 한다. 맨 앞이나 중간이나 절차는 같다.

public boolean insert(Object item){ int loc = 0;boolean moreToSearch = (loc<size); if(item!=null || isFull()) return false; Comparable x = (Comparable)item;while(moreToSearch){ if(x.compareTo(elements[loc])<0) moreToSearch = false; else{loc++; moreToSearch = (loc < size); } // while} for(int i=size; i>loc; i--) elements[loc] = item;elements[i] = elements[i-1]; size++; return true; }

자리를 만들어 주어야 하기 때문이다. 기존 요소들과의 비교는 compareTo 메소드를 사용하 게 된다. 따라서 인자로 주어진 객체는 물론 저장되어 있는 요소들은 Comparable 인터페이 스를 구현하고 있는 클래스의 인스턴스이어야 한다. 위 슬라이드에서 요소를 리스트 맨 끝 에 삽입할 경우에는 loc의 값 때문에 for 문은 실행되지 않는다.

public boolean delete(Object item){ if(item==null) return false;int loc = 0, comp = 0; boolean found = false; Comparable x = (Comparable)item;for(loc=0; loc<size; loc++){ comp = item.compareTo(elements[loc]); if(comp==0){ found = true;break; } else if(comp<0){found = false; break; } // for} if(found){ for(int i=loc; i<size-1; i++) size--;elements[i] = elements[i+1]; return true; else return false;} }

public boolean search(Object item){ int first = 0, mid = 0, last = size-1, comp = 0;boolean moreToSearch = true; boolean found = false; if(item!=null || isEmpty()) return false;Comparable x = (Comparable)item; while(moreToSearch && !found){ mid = (first + last) / 2; comp = x.compareTo(elements[mid]);if(comp==0) found = true; else if(comp<0){ last = mid - 1;moreToSearch = (first <= last); } else{first = mid + 1; moreToSearch = (first <= last); } } // whilereturn found; }

사전조건 : item!=null, 사후조건 : item 이 리스트에 있으면 없으면 truefalse 를를 반환한다 ,.

A B C D E F G H first= last= mid= A B C D E F G H first= last= mid= A B C D E F G H first= last=2mid=

슬라이드에 있는 예제는 C를 찾는 경우이고, 다음 슬라이드에 있는 예제는 F를 찾는 경우

A B C D E G H first=0last= mid= A B C D E G H first=4last= mid= A B C D E G H

first= mid=4last=

A B C D E G H first=5last= mid=?

알고리즘의 비교는 보통 성능의 비교 Which one is faster(efficient)? 비교하기 위해서는 비교 기준이 있어야 한다. 가장 단순한 방법 : 실행 시간 비교 주어진 입력에 대해 주어진 컴퓨터에서는 A 알고리즘이 B 알고리즘보다는 효율적이라는 것 밖에는 알 수 없다. 수행되는 프로그램 문장 수를 비교 프로그래밍 스타일에 의존한다. 프로그래밍 언어마다 다를 수 있다. 알고리즘의 핵심이핵심이 되는되는 연산의연산의 수행수행 횟수횟수 비교 검색 : 비교 연산 주어진 입력에 대한 함수로 횟수를 나타냄

1 부터 N까지 합산하는 알고리즘

알고리즘알고리즘 1.1. sum = 0; for(int i=1; i<=n; i++) sum = sum + count; 알고리즘알고리즘^ 2.2. sum = ((n+1) * n)/2; 알고리즘 1O( N ) 이지만 알고리즘 2O(1) 이다. 하지만 기준이 되는 연산이 다르다. 그러면 항상 알고리즘 2 가 알고리즘 1 보다 좋은가? N 이 매우 작은 경우에는 알고리즘 1 은 덧셈 연산만 사용하므로 더 좋을 수 있다. 알고리즘 이해도 측면에서 알고리즘 1 이 더 좋을 수 있다. Big-ON 이 매우 클 경우에 대한 비교 척도이다.

1 부터 N까지 합산하는 두 종류의 알고리즘을 Big-O 표기법을 이용하여 나타내보자. 우선 산술 연산을 기본 연산으로 생각하면 알고리즘 1 은 N번의 덧셈이 필요하므로 O(N)이며, 알 고리즘 2 는 입력의 크기와 상관없이 덧셈, 곱셈, 나눗셈이 각각 한번씩 필요하므로 O(1)이 다. 이 경우 N이 커지면 알고리즘 2 가 훨씬 성능이 좋다. 하지만 N이 작은 경우에는 알고 리즘 1 이 오히려 더 좋다. 그것은 덧셈이 곱셈 또는 나눗셈에 비해 매우 저렴한 연산이기 때문이다. 즉, Big-O는 요약하여 성능을 나타내므로 N이 매우 클 경우에만 정확하게 적용될 수 있다.

UnsortedList와 SortedList의 비교

O(N) O(N) O(N)

O(N) O(1) O(N)

delete 찾기 삭제 전체

O(N) O(N) O(N)

O(1) O(1) O(1)

insert 찾기 삽입 전체

O(N) search O(N) O(logN) 이진검색

size, isFull, isEmpty,reset, next O(1) O(1)

연산 UnsortedList SortedList

이 장에서 살펴본 정렬 리스트와 비정렬 리스트를 Big-O 표기법을 이용하여 비교하여 보자. 검색 연산의 경우에는 정렬 리스트는 이진 검색을 할 수 있으므로 성능이 더 좋다. 하지만 삽입은 정렬 리스트는 삽입할 위치를 찾아야 하므로 비정렬 리스트가 더 좋다. 삭제는 둘 다 삭제하고자 하는 요소를 찾아야 하는 비용이 소요되지만 비정렬 리스트의 경우에는 삭제 자체는 상수 시간에 할 수 있다.