270 likes | 436 Views
프로그래밍 기초. 제 13 주 2014 년 1 학기 강원대학교 컴퓨터학부 담당교수 : 정충교. 7 장 배열과 리스트 3: 여러 데이터에 이름 하나 Arrays and Lists: One Name for Many Data. 정렬과 탐색. Sorting and Searching. 삽입 정렬 (Insertion Sort). Simple sorts Insertion sort Selection sort Efficient sorts Merge sort Heapsort Quicksort
E N D
프로그래밍 기초 제 13주 2014년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교 강원대학교
7장 배열과 리스트 3:여러 데이터에 이름 하나Arrays and Lists:One Name for Many Data 강원대학교
정렬과 탐색 Sorting and Searching 강원대학교
삽입 정렬 (Insertion Sort) Simple sorts Insertion sort Selection sort Efficient sorts Merge sort Heapsort Quicksort Bubble sort and variants Bubble sort Shell sort Comb sort Distribution sort Counting sort Bucket sort Radix sort 강원대학교
삽입정렬 9 6 3 7 4 6 9 3 7 4 3 6 9 7 4 3 6 7 9 4 3 4 6 7 9 앞에서부터 차례로 정렬해 나간다. 빨간색 부분이 정렬된 부분 강원대학교
삽입정렬 9 6 3 7 4 6 9 3 7 4 3 6 9 7 4 3 6 7 9 4 3 4 6 7 9 6을 빨간 부분에 삽입한다. 3을 빨간 부분에 삽입한다. 7을 빨간 부분에 삽입한다. 4를 빨간 부분에 삽입한다. 강원대학교
삽입정렬 a 96 3 7 4 6 93 7 4 3 6 97 4 3 6 7 94 3 4 6 7 9 1번 원소 6을 빨간 부분에 삽입한다. insert(a, 1) 2번원소3을 빨간 부분에 삽입한다. insert(a, 2) 3번원소7을 빨간 부분에 삽입한다. insert(a, 3) 4번원소4를 빨간 부분에 삽입한다. insert(a, 4) 강원대학교
3번원소7을 빨간 부분에 삽입한다. insert(a, 3) 3 6 97 4 3 6 7 9 4 • void insert(int[] x, inti) • x[0], x[1], ..., x[i-1] 이 이미 정렬되어 있는 상태에서 • x[0], x[1], ..., x[i-1], x[i]가 정렬된 상태로 만들어준다. • x[i]를 x[0], x[1], ..., x[i-1] 사이의 적절한 위치에 삽입한다. 강원대학교
부분적으로 정렬된 (굵은 글씨 부분이 정렬되어 있음)다음의 정수 배열에서 [3 6 9 7 4] 7을 적절한 위치에 삽입하기 위하여, 7을임시변수temp에저장 이미 정렬된부분의 끝 원소인 9와7을비교한다. 7이 9보다앞에와야한다. 따라서9를오른쪽으로 한 위치이동(shift)시킨다(복사한다). [3 6 9 7 4] [3 6 9 9 4] // 7은이미temp에저장되어있다. 7과 6을비교한다. 6은 7보다 작다. 그러면 temp에 저장되어 있는 7을 6 다음의 위치에 복사한다. [3 6 9 94][3 6 7 9 4] 강원대학교
3번원소7을 빨간 부분에 삽입한다. insert(a, 3) 3 6 97 4 3 6 7 9 4 void insert(int[] x, inti) { x[i]를 임시 변수 temp에 복사; j = i-1; while (j >= 0 and temp < x[j] ) x[j]를 x[j+1]로 복사하고 j를 감소시킴 // 위치 이동 temp를 x[j+1]에 복사. } 강원대학교
void insert(int[] x, inti) x[0], x[1], ..., x[i-1] 이 이미 정렬되어 있는 상태에서 x[i]를 x[0], x[1], ..., x[i-1] 사이의 적절한 위치에 놓아준다. 만약 필요하다면 일부 숫자들을 오른쪽으로 위치 이동(shift)시킨다. x[i]를 임시변수temp에복사; j = i-1; while (j >= 0 and temp < x[j] ) x[j]를 x[j+1]로 복사하고j를감소시킴// 위치이동 temp를x[j+1]에 복사. 강원대학교
삽입정렬 n개의 요소가 있는 배열을 정렬하기 위하여 insert(...) 메소드를 n-1번 호출한다. 강원대학교
두 개의 메소드로 구현함 • void insert(int[] x, inti) • x[0], x[1], ..., x[i-1] 이 이미 정렬되어 있는 상태에서 • x[0], x[1], ..., x[i-1], x[i]가 정렬된 상태로 만들어준다. • x[i]를 x[0], x[1], ..., x[i-1] 사이의 적절한 위치에 놓아준다. • void insertionSort(int[] x, int n) • 배열 x의 앞부분 n개 원소를 정렬한다. • x[0], x[1], ..., x[n-1]을 정렬된 상태로 만든다. 강원대학교
// x[i]을 이미 정렬된 값들 x[0], x[1], ..., [i-1] 중 올바른 위치에 끼워 넣는다. public static void insert (int[] x, inti) { int temp = x[i]; // 값을 임시 저장소에 보관 int j = i-1; while ( j >= 0 && temp <x[j]) { // temp 값을 끼워 넣을 장소를 찾음 x[j+1] = x[j]; // 오른쪽으로 이동 j--; } x[j+1]= temp; // temp 값(x[i])을 올바른 위치에 끼워 넣음 } // n은 배열 x에 들어 있는 데이터 개수 public static void insertionSort(int[] x, int n) { for (inti = 1; i < n; i++) insert(x, i); } 강원대학교
Scanner input = new Scanner(System.in); int []numbers = new int[1000]; // 최대 1000개의 정수를 저장할 수 있는 배열 int size; // 실제로 저장되어 있는 정수 개수 System.out.print("데이터 개수를 입력하시오: "); size = input.nextInt(); System.out.print(size + "개의 정수를 입력하시오: "); for (int i = 0; i < size; i++) numbers[i] = input.nextInt(); System.out.println(); insertionSort(numbers, size); System.out.print("Sorted: "); for (int i = 0; i < size; i++) System.out.print(numbers[i]+ " "); System.out.println(); 강원대학교
프로그램 설명 • 배열은 부분적으로 채워질 수 있다. 유효한 원소 개수는 x.length가 아니라 size이다. • 크기가 n 인 데이터 집합에 대한 삽입 정렬은 많아야 ½(n2 – n) 의 비교를 수행한다. • 만약 데이터가 이미 정렬되어 있다면 삽입 정렬은 n –1비교만을 하게 된다. 강원대학교
탐색 (Search) • 선형 탐색 (linear search) • 이진 탐색 (binary search) 강원대학교
선형 탐색 x[0]에서 시작하여 배열 내에 있는 각 항목을 키(key)와 비교한다. key == x[0] 인가? key == x[1] 인가? key == x[2] 인가? ... 만약 키가 x[i]와 일치하면, 탐색은 종료되고, i를 반환한다. 만약 키를 배열에서 찾지 못하면, 키 발견 실패를 의미하는 값(통상 -1)을 반환한다. 강원대학교
선형 탐색 public static int search(int[] x, int n, int key) { // x에서의 키 위치를 반환 // 만약 키를 찾지 못하면 -1을 반환 // 배열 x는 부분적으로만 채워짐. n은 x에 있는 데이터의 개수 for ( int i = 0; i < n; i++) if (key == x[i]) // 키를 발견함 return i; // 인덱스를 반환 return -1; // 키를 찾지 못함 } 강원대학교
이진 탐색 이진 탐색(binary search)은 선형 탐색보다 훨씬 성능이 좋다. - 더 적은 비교 연산 - 더 짧은 실행 시간 이진 탐색을 위해서는 배열이 미리 정렬되어 있어야 한다. 강원대학교
이진 탐색 다음의 정렬된 배열에서 키 27을 탐색 [3 5 6 9 11 23 25 26 27 29 33 35 36 37 39 42 45 46 48 58 62 67 70]. 강원대학교
한 번의 비교 후, 배열의 절반은 제외된다. 강원대학교
두 번 비교 후의 이진 탐색 강원대학교
단 세 번의 비교로 27을 찾았다. 강원대학교
// x는 n개의 정수가 정렬된 배열이다. 키는 정수 값을 가진다. // x는 오름차순으로 정렬되어 있다. static int search(int[] x , int n, int key) { int lo = 0; // 배열의 최소 인덱스 int hi = n-1; // 최대 인덱스 int mid; // 중앙 인덱스 while (hi >= lo) { mid = (hi + lo) / 2; // 중앙 인덱스 계산 if (key == x[mid]) return mid; //키를 발견 -- 종료 if (key < x[mid]) hi = mid - 1; //x[mid]에서 x[hi]까지 제외 else lo = mid + 1; // x[lo]에서 x[mid]까지 제외 } return -1; // 키를 발견하지 못함 } 강원대학교
강원대학교 .
이진 탐색 n 개 항목의 리스트에 대하여 선형 탐색은 평균적으로 n/2 위치를 검사한다. 이진 탐색은 약 log2n – 1 위치들만 검사한다. n n/2 (선형 탐색)log2n –1 (이진 탐색) 210 =1024 512 9 215 =32768 16384 14 220 =1048576 524288 19 225 =33554432 16777216 24 강원대학교