Selection Sort
1st : finding the smallest integer;
2nd : exchange (함수 or macro);for (i=0; i<n; i++){
Examine list[i] to list[n-1]
and suppose that the smallest integer is at list[min]
Interchange list[i] and list[min]
}
// Swap Function
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
// Call : swap(&a, &b)
// Swap Macro
#define SWAP(x,y,t) ((t) = (x), (x) = (y), (y) = (t)
// Selection Sort
void sort(int list[], int n){
int i, j, min, temp;
for(i = 0; i < n-1; i++){
min = i;
for(j = i+1; j < n; j++)
if(list[j] < list[min])
min = j;
SWAP(list[i], list[min], temp);
}
}
Binary Search
1st : 아직 검사할 정수가 남아 있는지 결정
2nd : searchnum과 list[middle] 비고while(there are more integers to check){
middle = (left + right) / 2;
if (searchnum < list[middle])
return middle;
else left = middle + 1;
//Compare Function
int compare(int x, int y){
if(x < y) return -1;
else if(x == y) return 0;
else return 1;
}
// Compare Macro
#define COMPARE (x,y) ((x) < (y)) ? -1: ((x) == (y)) ? 0 : 1)
// 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;
}
Direct recursion : 직접 순환. 함수가 그 수행이 완료되기 전에 자기 자신을 다시 호출
Indirect recursion : 간접 순환. 호출 함수를 다시 호출하게 되어 있는 다른 함수를 호출
[Binomial Coefficients] : 조합의 재귀적 표현
[Fatorial] : 팩토리얼
[Binary Search] : 이진 탐색
BSrch[key, left, right]
if key < list[middle]
BSrch[key, left, middle-1]
if key = list[middle]
list[middle]
if key > list[middle]
BSrch[key, middle+1, right]
// 이진 탐색 재귀적 구현
int binsearch(int list[], int searchnum, int left, int right){
int middle;
if(left <= right){
middle = (left + right) / 2;
switch(COMPARE(list[middle], searchnum)){
case -1:
return binsearch(list, searchnum, middle + 1, right);
case 0: return middle;
case 1:
return binsearch(list, searchnum, left, middle - 1);
}
}
return -1;
}
fn = 0 (if n = 0)
fn = 1 (if n = 1)
fn = fn-1 + fn-2 (if n > 1)
// 일반 함수
int fibo(int n){
int g, h, f, i;
if(n>1){
g = 0;
h = 1;
for(i = 2; i <= n; i++){
f = g + h;
g = h;
h = f;
}
}
else f = n;
return f;
}
// 재귀 함수
int rfibo(int n){
if(n > 1)
return rfibo(n-1) + rfibo(n-2);
else return n;
}
// 순열의 재귀적 생성
void perm(char *list, int i, int n){
int j, temp;
if(i == n){
for(j = 0; j <= n; j++)
printf("%c", list[j]);
printf("\n");
} else {
// list에 1개 이상의 문자가 들어있으면 재귀적으로 생성
for(j = i; j <= n; j++){
SWAP(&list[i], &list[j]);
perm(list, i + 1, n);
SWAP(&list[i], &list[j]);
}
}
}
데이터 타입 : 객체(object)와 그 객체를 가지고 하는 연산(operation)들의 모음
char, int, float, double ...array, struct추상 데이터 타입(ADT, Abstract Data Type) : 객체와 연산의 명세가 구현으로부터 분리된 데이터 타입.
→ 내부적 표현 or 구현에 대한 설명이 필요 없음
[ADT Natural_Number ]
Object : 0에서 시작해서 컴퓨터상의 최대 정수 값(INT_MAX)까지 순서화된 정수의 부분 범위
Function:
Nat_Number의 모든 원소 x,y 그리고 Boolean의 원소 T
NaturalNumberZero()::= 0
BooleanIsZero(x)::=
if (x) return FALSE
else return TRUE
BooleanEqual(x,y)::=
if(x==y) return TRUE
else return FALSE
NaturalNumberSuccessor(x)::=
if(x == INTMAX) return x
else return x+1
_NaturalNumberAdd(x,y)::=
if((x+y) <= INT_MAX) return x+y
else return INT_MAX
NaturalNumberSubtract::=
if(x<y) return 0
else return x-y
자세한 구현을 피하기 위해 ADT 사용
Fixed space requirement : 고정 공간 요구. 프로그램 입출력의 횟수나 크기와 관계 없는 공간 요구
Variable space requirement : 특정 인스턴스에 의존하는 크기를 가진 구조화 변수의 공간
전체 프로그램이 필요한 공간 : 고정 공간 + 가변 공간
→ 공간 복잡도 분석시에는 가변 공간 요구에만 관심 가짐.
공간 복잡도 구하는 예시
// 단순 산술 함수
float abc(float a, float b, float c){
return a+b+b*c+(a+b-c)/(a+b)+4.0;
→
// 리스트에 있는 수를 합산하기 위한 반복 함수
float sum(float list[], int n){
int i;
float tempSum = 0;
for(i = 0; i < n; i++)
tempSum += list[i];
return tempSum;
}
→ : 인자가 pass-by-reference일 때(포인터로 전달)
→ : 인자가 pass-by-value일 때(전체 배열 복사)
// 리스트에 있는 수를 합산하기 위한 순환 함수
float rsum(float list[], int n){
if(n) return rsum(list, n-1) + list[n-1];
return 0;
}
→ 같은 함수라도 순환 함수로 구현하면 공간 요구가 더 커짐.
소요되는 총 시간 : 컴파일 시간 + 실행 시간
→ 시간 복잡도 분석시에는 실행 시간에만 관심 가짐.
프로그램 단계 program step : 실행 시간이 인스턴스 특성에 구문적으로 / 의미적으로 독립성을 갖는 프로그램의 단위
시간 복잡도 구하는 예시
// 리스트에 있는 수를 합산하기 위한 반복 함수
float sum(float list[], int n){
int i;
float tempSum = 0;
for(i = 0; i < n; i++)
tempSum += list[i];
return tempSum;
}
→ 2n + 3

f(x) = O(g(x))
↔ x > k 일 때 항상 를 만족하는 상수 C와 k 가 존재한다.

f(x) = (g(n))
↔ x > k 일 때 항상 를 만족하는 상수 C와 k 가 존재한다.
f(x) = (g(n))
↔ f(x) = O(g(x)) && f(x) = Ω(g(x))
void add(int a[][MAX_SIZE] ...){
int i, j;
for(i = 0; i < rows; i++)
for(j = 0; j < cols; j++)
c[i][j] = a[i][j] + b[i][j];
}
→ 시간 복잡도 : (rows * cols)
// 매직 스퀘어 프로그램
int main(void){
// 정방형을 반복적으로 생성
int square[MAX_SIZE][MAX_SIZE];
int i, j, row, column; // 지수
int count; // 계수
int size; // 정방형의 크기
printf("Enter the size of the square: ");
scanf("%d", &size);
// 입력에 오류가 있는지 체크
if(size < 1 || size > MAX_SIZE + 1){
fprintf(stderr, "Error! Size is out of range\n");
exit(1);
}
if(!(size % 2)){
fprintf(stderr, "Error! Size is even\n");
exit(1);
}
for (i=0; i<size; i++)
for(j=0; j<size; j++)
square[i][j] = 0;
square[0][(size - 1) / 2] = 1; // 첫 번째 행의 중앙에 1 넣기
// i와 j는 현재 위치
i = 0;
j = (size - 1) / 2;
for(count = 2; count <= size * size; count++){
// 다음 위치 계산
row = (i - 1 < 0) ? size - 1 : i - 1; // 위로
column = (j - 1 < 0) ? size - 1 : j - 1; // 왼쪽으로
// 이미 채워져 있는지 확인
if(square[row][column]){ // 아래로
i = (++i) % size;
}
else{ // 정방형이 비어있을 경우
i = row;
j = column;
}
square[i][j] = count;
}
// 정방형 출력
printf("\nMagic Square of size %d: \n\n", size);
for(i = 0; i < size; i++){
for(j = 0; j < size; j++)
printf("%5d", square[i][j]);
printf("\n");
}
printf("\n\n");
}
시간 복잡도 : (n2)



| Method1 | Method2 | |
|---|---|---|
| Start Timing | Start = clock(); | Start = time(NULL); |
| Stop Timing | Stop = clock(); | Stop = time(NULL); |
| Type returned | Clock_t | Time_t |
| Result in second | Duration = ((double)(Stop-Start))/CLOCKS_PER_SEC; | Duration=(double)difftime(Stop,Start) |