1. Algorithm
정확한 정의는 아직 없다. 하지만 우리가 서로 공통적으로 이해하고 있는 부분이 있다.
1) algorithm 정의
명령들의 유한 집합이며 이들을 따라가면 특정 업무를 수행할 수 있다.
2) algorithm 정의의 기준
1> input (없을 수도 있고 많을 수도 있다.)
2> output (적어도 하나의 결과)
3> Definiteness (각각의 명령은 명확하고 올바르게 정의되어야 한다.)
4> Finiteness
- 운영체제의 경우 무한히 수행되기도 한다.
- 어떤 학자들은 무한한 것을 algorithm이라 하지 않고 procedure이라고 하기도 함
5> Effectiveness
(물론 5가지 모든 조건을 만족하지 않을 수 있다.)
2. Selection Sort
1> 정렬 증명: loop invariant
1) 기본
1> 정의: 첫 번째 자료를 두 번째 자료부터 마지막 자료까지 차례대로 비교하여 가장 작은 값을 찾아 첫 번째에 놓고, 두 번째 자료를 세 번째 자료부터 마지막 자료까지와 차례대로 비교하여 그 중 가장 작은 값을 찾아 두 번째 위치에 놓는 과정을 반복하며 정렬을 수행한다.
2> 제자리 정렬 (in-place sorting) -> 다른 추가 메모리를 요구하지 않음
2) 구체적인 과정
1> 1st task: 주어진 array 전체(0~MAX)에서 가장 작은 원소를 찾는다.
2> 2nd task: '그 작은 원소'와 'array에서 0번째 원소'를 교체한다.
3> 1>~2>를 1번째 원소부터 마지막 원소까지의 범위에서 시행
4> 이를 하나의 원소만 남을 때까지 반복
3) 구현
0> pseudo code
for (int i = 0; i < n; i++) { // 1) Examine list[i] to list[n-1] and suppose that the smallest one is at list[min] // 2) Interchange list[i] and list[min] }
1> 기본 구현
#include <stdio.h> #define MAX 100 int main() { int N; scanf("%d", &N); int list[MAX]; for (int i = 0; i < N; i++) { scanf("%d", &list[i]); } int min, idx, temp; for (int i = 0; i < N; i++) { min = 9999; // 추후 들어올 수 있는 원소들보다 큰 값으로 min을 설정 for (int j = i; j < N; j++) { if (min > list[j]) { min = list[j]; idx = j; } } temp = list[i]; list[i] = list[idx]; list[idx] = temp; } for (int i = 0; i < N; i++) { printf("%d\n", list[i]); } }
2> swap function
oid swap(int *x, int *y) { int temp = *x; *x = *y; *y = temp; }
void swap(int &a, int &b) { int temp = a; a = b; b = temp; }
3> macro version of swap
#define SWAP(x,y,t) ((t) = (x), (x) = (y), (y) = (t))
4> macro를 이용한 selection sort
void sort(int list[], int n) { int min, temp; for (int i = 0; i < n - 1; i++) { min = i; // 시작점 i를 최소로 먼저 초기화한다. for (int j = i + 1; j < n; j++) { if (list[j] < list[min]) { min = j; } SWAP(list[i], list[min], temp); } } }
결론은 함수나 매크로를 정의해두면 필요할 때마다 쓸 수 있어서 편하다.
3. Binary Search
1) 기본
1> 정의:
- 가정: 이미 n개의 숫자가 정렬되어 있을 때,
- 찾는 숫자가 이 배열 안에 있는지 확인한다.
- 있다면 그 위치의 배열의 index를 return하고, 없다면 -1을 return
2) 구체적인 과정
0> 초기 설정
- list: 정렬할 배열
- searchNum: 찾고자 하는 수
- left, right: 배열의 시작, 끝
(middle은 left와 right가 계산되고서 연산한다. -> 그래서 while문 내부에 넣는다.)
- middle = (left + right)/2: 우리가 찾고자하는 searchNum과 비교한다.
1> 1st task: searchNum이 있는지 확인한다.
(어떻게 확인할 것인가?)
(middle은 left와 right가 계산되고서 연산한다. -> 그래서 while문 내부에 넣는다.)
- middle = (left + right)/2: 우리가 찾고자하는 searchNum과 비교한다.
2> 2nd task: middle과 searchNum과 비교한다.
- searchNum = middle : searchNum을 찾았으니
=> middle을 return
- searchNum < middle : searchNum이 존재할 경우, list[left] ~ list[middle-1] 사이에 있으니
=> right에 middle-1을 대입
- searchNum > middle: searchNum이 존재할 경우, list[middle+1] ~ list[right] 사이에 있으니
=> left에 middle+1을 대입
cf> searchNum이 list 안에 있는지 확인하는 방법
binary search를 진행하는 동안에 searchNum이 없다면 left와 right가 교차하게 된다.
따라서 left와 right의 크기를 비교하는 task를 선행하고 middle과 searchNum을 비교한다.
3) 구현
0> pseudo code
int BinarySearch(int list[], int left, int right, int searchNum) { // 0> 초깃값들은 paramter에서 제공받는다. while (left <= right) // 1st task-1: searchNum이 list 내부에 있는지 { // 1st task-2: middle은 left와 right이 계산되고서 구할 수 있다. // 2nd task: searchNum과 middle과의 대소비교로 searchNum의 위치 찾기 // 2-1, 2-2, 2-3 (searchNum과 middle이 같거나 더 크거나 작거나에 따라) }
1> 기본 구현
int BinarySearch(int list[], int left, int right, int searchNum) { while (left <= right) { int middle = (left + right) / 2; if (searchNum == middle) { return middle; } else if (searchNum < middle) { right = middle - 1; } else { left = middle + 1; } } }
2> compare function
- 대소 관계에 따라 -1, 0, 1이 나오게 할 것이다.
int compare(int x, int y) { if (x < y) return - 1; else if (x == y) return 0; else return 1; }
3> macro version of compare
#define COMPARE(x, y) (((x) < (y))? -1:((x)==(y))? 0: 1)
4> macro를 이용한 binary search
int binsearch (int list[], int searchnum, int left, int right) { int middle; while (left <= right) { middle = (left + right) / 2; switch (COMPARE(list[middle],searchnum)) { case -1: left = middle + 1; break; case 0: return middle; case 1: right = middle + 1; } } return -1; }
'자료구조' 카테고리의 다른 글
1-5강 - Performance analysis (2) 점근 표기법 (0) | 2020.03.31 |
---|---|
1-5강 - Performance analysis (1) 공간 복잡도, 시간 복잡도 (0) | 2020.03.31 |
1-4강 - Data abstraction (0) | 2020.03.30 |
1-3강 - Algorithm specification (2) 재귀 알고리즘 (0) | 2020.03.30 |
1-1강 - System life cycle (0) | 2020.03.18 |