chap 1:자료구조와알고리즘 -...
TRANSCRIPT
C로 쉽게 풀어쓴 자료구조
Data Abstraction
C 언어의기본자료형 (basic data type) : char, int, float, double
-키워드 : short, long, unsigned
• 자료의그룹화 (composite data type) :배열(array), 구조(structure)
- int list[5] : 정수형배열,
-구조
struct student { char last_name; int student_id; char grade;
}
• 포인터자료형 (pointer) : 정수형, 실수형, 문자형, float형포인터
int i, *pi; float *pf;
• 사용자정의(user-defined) 자료형
C로 쉽게 풀어쓴 자료구조
알고리즘의성능분석
알고리즘의 성능 평가 (performance evaluation)
수행 시간 측정 (performance measurement)
두 개의 알고리즘의 실제 수행 시간을 측정하는 것
실제로 구현하는 것이 필요
동일한 하드웨어를 사용하여야 함
알고리즘의 복잡도 분석 (performance analysis)
직접 구현하지 않고서도 수행 시간을 분석하는 것
알고리즘이 수행하는 연산의 횟수를 측정하여 비교
일반적으로 연산의 횟수는 n의 함수
시간 복잡도 분석: 수행 시간 분석
공간 복잡도 분석: 수행시 필요로 하는 메모리 공간 분석
C로 쉽게 풀어쓴 자료구조
수행시간측정
컴퓨터에서 수행시간을 측정하는 방법에는 주로 clock 함수가 사용된다.
clock_t clock(void);
clock 함수는 호출되었을 때의 시스템 시각을 CLOCKS_PER_SEC 단위로 반환
Ex) 수행시간을 측정하는 전형적인 프로그램
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main( void )
{
clock_t start, finish;
double duration;
start = clock();
// 수행시간을측정하고하는코드....
// ....
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("%f 초입니다.\n", duration);
}
알고리즘의 성능분석
C로 쉽게 풀어쓴 자료구조
정의
• 공간 복잡도(space complexity)
프로그램을 실행시켜 완료하는데 필요한 공간의 양( amount of memory )
• 시간 복잡도(time complexity)
프로그램을 실행시켜 완료하는데 필요한 컴퓨터 시간의 양 (amount of
computer time)
알고리즘의성능분석
• 복잡도 분석
C로 쉽게 풀어쓴 자료구조
공간복잡도(Space complexity)
프로그램에필요한공간
1) 고정공간요구 (fixed space requirements) : 프로그램입출력의
횟수나크기와관계없는공간요구
-명령어공간, 단순변수, 고정크기의구조화변수, 상수
2) 가변공간요구 (variable space requirements) : 해당문제의
인스턴스 (I)에의존하는공간
-가변공간, 스택공간
total space requirement S(P)
공간요구량 : S(P) = c + SP(I)
c : constant representing the fixed space requirements
Sp(I) : function of some characteristics of the instance I
C로 쉽게 풀어쓴 자료구조
Space complexity
Ex
float abc(float a, float b, float c) {
return a+b+b*c+(a+b-c)/(a+b)+4.00;
}
input - three simple variables
ouput - a simple variable
*고정 공간 요구만을 가짐(fixed space requirements only)
⇨ Sabc(I) = 0
C로 쉽게 풀어쓴 자료구조
Space complexity
Ex [Iterative version] – sum
float sum(float list[], int n) {
float tempsum = 0;
int i;
for(i = 0; i < n; i++)
tempsum += list[i];
return tempsum;
}
• 가변공간요구 : 배열 (크기 n)
- C 경우 : 배열의 첫번째 요소의 주소 전달
. Ssum(n) = 0
C로 쉽게 풀어쓴 자료구조
really concerned only with the program’s execution
time, Tp
count the number of operations the program performs -> give a machine-independent estimation
• 프로그램 P에의해소요되는시간 : T(P)
T(P) = 컴파일시간 (compile time)
+TP (실행시간 :run or execution time )
시간복잡도분석(Time complexity)
C로 쉽게 풀어쓴 자료구조
시간복잡도분석(Time complexity)
시간 복잡도는 알고리즘을 이루고 있는 연산들이 몇 번이나 수행되는지를 숫자로 표시
알고리즘이 수행하는 연산의 개수를 계산하여 두 개의 알고리즘비교
연산의 수행횟수는 고정된 숫자가 아니라 입력의 개수 n에 대한함수
3n+2
If n=2, 연산의수 = 8
5n2 +6
If n=2, 연산의수 =26
프로그램 A 프로그램 B
워드2005 워드2000
C로 쉽게 풀어쓴 자료구조
정의 : 프로그램 단계(program step)
실행 시간이 인스턴스 특성에 구문적으로 또는
의미적으로 독립성을 갖는 프로그램의 단위
a = 2
⇨ 1 step !!
a = 2*b+3*c/d-e+f/g/a/b/c
시간복잡도분석(Time complexity)
C로 쉽게 풀어쓴 자료구조
Ex [Iterative summing of a list of numbers]
float sum(float list[], int n) {
float tempsum=0;
count++; /* for assignment */
int i;
for(i = 0; i < n; i++) {
count++; /* for the for loop */
tempsum += list[i];
count++; /*for assignment*/
}
count++; /* last execution of for */
count++; /* for return */
return tempsum;
}
단계의 계산 (방법 1) - 전역 변수 count 의 사용
시간복잡도분석(Time complexity)-1
C로 쉽게 풀어쓴 자료구조
a simpler program :
- computes the same value for count
float sum(float list[], int n) {
float tempsum=0;
int i;
for(i = 0; i < n; i++)
count+=2;
count += 3;
return 0;
}
총 2n + 3 steps
시간복잡도분석(Time complexity)-1
C로 쉽게 풀어쓴 자료구조
Ex [Recursive summing of a list of numbers]
float rsum(float list[], int n) {
count++;
if (n) {
count++;
return rsum(list,n-1)+list[n-1];
}
count++;
return list[0];
}
n = 0 -> 2 (if, 마지막 return)
n > 0 -> 2 (if, 처음 return) : n회호출
∴ 2n + 2 steps
시간복잡도분석(Time complexity)-1
C로 쉽게 풀어쓴 자료구조
※ 2n + 3 (iterative) > 2n + 2 (recursive)
⇨ Titerative > Trecursive ??
시간복잡도분석(Time complexity)-1
C로 쉽게 풀어쓴 자료구조
단계의 계산 (방법 2)
- 테이블 방식(tabular method) : 단계수 테이블
① 문장에 대한 단계수 : steps/execution, s/e
② 문장이 수행되는 횟수 : 빈도수(frequency)
- 비실행 문장의 빈도수 = 0
③ 총 단계수 = 빈도수 × s/e
시간복잡도분석(Time complexity)-2
C로 쉽게 풀어쓴 자료구조
Ex [Iterative function to sum a list of numbers]
Statem ent s/e Frequency Total steps
float sum (float list[],int n) {
float tem psum =0;
int i;
for(i=0;i<n;i++)
tem psum +=list[i];
return tem psum ;
}
0
1
0
1
1
1
0
0
1
0
n+1
n
1
0
0
1
0
n+1
n
1
0
total 2n+3
Step count table
시간복잡도분석(Time complexity)-2
C로 쉽게 풀어쓴 자료구조
Ex [Recursive function to sum a list of numbers]
Statement s/e Frequency Total steps
float rsum(float list[],int n) {
if(n)
return rsum(list,n-1)+list[n-1];
return list[0];
}
0
1
1
1
0
0
n+1
n
1
0
0
n+1
n
1
0
total 2n+2
Step count table for recursive summing function
시간복잡도분석(Time complexity)-2
C로 쉽게 풀어쓴 자료구조
Ex [Matrix addition]
Statement s/e Frequency Total steps
void add(int a[][M_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];
}
0
0
1
1
1
0
0
0
rows+1
rows· (cols+1)
rows·cols
0
0
0
rows+1
rows·cols+rows
rows·cols
0
total 2n+2
Step count table for matrix addition
2rows・cols + 2rows + 1
시간복잡도분석(Time complexity)-2
C로 쉽게 풀어쓴 자료구조
Asymptotic Notation 점근 표기법(O,,)
comparing time complexities
- exist different algorithms for the same task
- which one is faster ?
algorithm 1 algorithm 2task
count
f(n) g(n)
C로 쉽게 풀어쓴 자료구조
• 단계수 (step count ) : 동일 기능의 두 프로그램의 시간
복잡도 비교 or 인스턴스 특성의 변화에 따른 실행 시간증가 예측
- worst case step count : 최대수행단계수
- average step count : 평균수행단계수
정확한단계의 측정이어렵다.
• 정확한단계의계산 : 무의미
- A의단계수 = 3n + 3, B의단계수 = 100n + 10 ⇨ TA << TB
A ≃ 3n (or 2n), B ≃ 100n (or 80n, 85n) ⇨ TA << TB
Asymptotic Notation 점근 표기법(O,,)
C로 쉽게 풀어쓴 자료구조
빅오 표기법
자료의 개수가 많은 경우에는 차수가 가장 큰 항이 가장영향을 크게 미치고 다른 항들은 상대적으로 무시될 수 있다.
(예) n=1,000 일 때, T(n)의 값은 1,001,001이고 이중에서 첫 번째 항인 n2의 값이 전체의 약 99%인 1,000,000이고 두 번째 항 n의 값이 1000으로 전체의 약 1%를 차지한다.
따라서 보통 시간복잡도 함수에서 가장 영향을 크게 미치는 항만을 고려하면 충분하다.
빅오표기법: 연산의 횟수를 대략적(점근적)으로 표기한 것
두개의 함수 f(n)과 g(n)이 주어졌을 때,
모든 n≥n0에 대하여 |f(n)| ≤ c|g(n)|을 만족하는 2개의 상수 c와 n0가 존재하면 f(n)=O(g(n))이다.
빅오는 함수의 상한을 표시한다. (예) n≥5 이면 2n+1 <10n 이므로 2n+1 = O(n)
입력의 개수 n
연산의 횟수 ))(( nfO
)(nf
0n
n=1000인 경우
T(n)= n2 + n + 1
99% 1%
C로 쉽게 풀어쓴 자료구조
Asymptotic Notation 점근 표기법
정의 [Big "oh"] f(n) = Ο(g(n))
f(n)=Ο(g(n)) iff ∃c,n0 > 0, s.t f(n) ≤ cg(n) ∀n, n≥n0
C로 쉽게 풀어쓴 자료구조
Asymptotic Notation
n0 n
g(n)
f(n)
• 예제
n ≥ 2, 3n + 2 ≤ 4n ⇨ 3n + 2 = Ο(n)
n ≥ 3, 3n + 3 ≤ 4n ⇨ 3n + 3 = Ο(n)
n ≥ 10, 100n + 6 ≤ 101n ⇨ 100n + 6 = Ο(n)
n ≥ 5, 10n2
+ 4n + 2 ≤ 11n2⇨ 10n
2+ 4n + 2 = Ο(n
2)
n ≥ 4, 6*2n
+ n2
≤ 7*2n⇨ 6*2
n+ n2 = Ο(2
n)
n ≥ 2, 3n + 3 ≤ 3n2⇨ 3n + 3 = Ο(n
2)
n ≥ n0인모든 n과임의의상수 c에대해
3n + 2 ≤ c 가 false인경우가존재하면 3n+2≠Ο(1)
10n2
+ 4n + 2 ≠ Ο(n)
C로 쉽게 풀어쓴 자료구조
※ Ο(1)<Ο(log n)<Ο(n)<Ο(n log n)<Ο(n2)<Ο(n
3)<Ο(2
n)
※ f(n) = Ο(g(n))
- n ≥ n0인모든 n에대해 g(n) 값은 f(n)의상한값
- g(n)은조건을만족하는가장작은함수여야함
Asymptotic Notation
C로 쉽게 풀어쓴 자료구조
Practical Complexities
class of time complexities O(1): constant
O(log2n): logarithmic
O(n): linear
O(n·log2n): log-linear
O(n2): quadratic
O(n3): cubic
O(2n): exponential
O(n!): factorial
polynomial
time
exponential
time
실용적인복잡도tractable
problem
Intractable
(hard)
problem
C로 쉽게 풀어쓴 자료구조
빅오 표기법의 종류
O(1) : 상수형
O(logn) : 로그형
O(n) : 선형
O(nlogn) : 로그선형
O(n2) : 2차형
O(n3) : 3차형
O(nk) : k차형
O(2n) : 지수형
O(n!) : 팩토리얼형
C로 쉽게 풀어쓴 자료구조
Practical Complexities
function value
instance characteristic n
time name 1 2 4 8 16 32
1
log n
n
n log n
n2
n3
constant
logarithmic
linear
log linear
quadratic
cubic
1
0
1
0
1
1
1
1
2
2
4
8
1
2
4
8
16
64
1
3
8
24
64
512
1
4
16
64
256
4096
1
5
32
160
1024
32768
2n
n!
exponential
factorial
2
1
4
2
16
24
256
40326
655536
20922789888000
4294967296
263131033
C로 쉽게 풀어쓴 자료구조
빅오 표기법이외의 표기법
.
빅오메가 표기법
모든 n≥n0에 대하여 |f(n)| ≥ c|g(n)|을만족하는 2개의 상수 c와 n0가 존재하면f(n)=Ω(g(n))이다.
빅오메가는 함수의 하한을 표시한다.
(예) n ≥ 5 이면 2n+1 <10n 이므로 n = Ω(n)
빅세타 표기법
모든 n≥n0에 대하여 c1|g(n)| ≤ |f(n)| ≤ c2|g(n)|을 만족하는 3개의 상수 c1, c2와n0가 존재하면 f(n)=θ(g(n))이다.
빅세타는 함수의 하한인 동시에 상한을 표시한다.
f(n)=O(g(n))이면서 f(n)= Ω(g(n))이면f(n)= θ(n)이다.
(예) n ≥ 1이면 n ≤ 2n+1 ≤ 3n이므로2n+1 = θ(n)
입력의 개수 n
연산의 수
))(( nf
))(( nfO
)(nf
상한
하한
0n
C로 쉽게 풀어쓴 자료구조
최선, 평균, 최악의 경우
알고리즘의 수행시간은 입력 자료 집합에 따라 다를 수 있다.
(예) 정렬 알고리즘의 수행 시간은 입력 집합에 따라 다를 수 있다.
최선의 경우(best case): 수행 시간이 가장 빠른 경우
평균의 경우(average case): 수행시간이 평균적인 경우
최악의 경우(worst case): 수행 시간이 가장 늦은 경우
최악의 경우
최선의 경우
평균적인 경우
A B C D E F G입력 집합
수행시간
100
50
최선의 경우: 의미가 없는 경우가 많다.
평균적인 경우: 계산하기가 상당히어려움.
최악의 경우: 가장 널리 사용된다. 계산하기 쉽고 응용에 따라서 중요한 의미를 가질 수도 있다.
(예) 비행기 관제업무, 게임, 로보틱스
C로 쉽게 풀어쓴 자료구조
최선, 평균, 최악의 경우
(예) 순차탐색 최선의 경우: 찾고자 하는 숫자가
맨앞에 있는 경우∴ O(1)
최악의 경우: 찾고자 하는 숫자가맨뒤에 있는 경우
∴ O(n)
평균적인 경우: 각 요소들이 균일하게 탐색된다고 가정하면
(1+2+…+n)/n=(n+1)/2
∴ O(n)
C로 쉽게 풀어쓴 자료구조
자료 구조의 C언어 표현방법
자료구조와 관련된 데이터들을 구조체로 정의
연산을 호출할 경우, 이 구조체를 함수의 파라미터로 전달
(예)
// 자료구조 스택과 관련된 자료들을 정의typedef int element;typedef struct {
int top;element stack[MAX_STACK_SIZE];
} StackType;
// 자료구조 스택과 관련된 연산들을 정의void push(StackType *s, element item){
if( s->top >= (MAX_STACK_SIZE -1)){stack_full();return;
}s->stack[++(s->top)] = item;
}
자료구조의 요소
관련된 데이터를 구조체로 정의
연산을 호출할때 구조체를함수의 파라미터로 전달
C로 쉽게 풀어쓴 자료구조
자료구조 기술규칙
상수 대문자로 표기(예) #define MAX_ELEMENT 100
변수의 이름 소문자를 사용하였으며 언더라인을 사용하여 단어와 단어를 분리(예) int increment; int new_node;
함수의 이름 동사를 이용하여 함수가 하는 작업을 표기(예) int add(ListNode *node) // 혼동이 없는 경우
int list_add(ListNode *node) //혼동이 생길 우려가 있는 경우
typedef의 사용 C언어에서 사용자 정의 데이터 타입을 만드는 경우에 쓰이는 키워드
(예) typedef int element; typedef struct ListNode {
element data; struct ListNode *link;
} ListNode;
typedef <새로운 타입의 정의> <새로운 타입 이름>;
C로 쉽게 풀어쓴 자료구조
시간복잡도함수 n2
+ 10n + 2 를빅오표기법으로나타내면?
빅오표기법을수행시간이적게걸리는것부터나열하면?
Ο(1) Ο(n) Ο(log n) Ο(n2) Ο(n log n) Ο(n!) Ο(2
n)
다음프로그램의시간복잡도를빅오표기법으로나타내면?
for (i=n-1 ; i!=0 ; i/=2 ) k++;
Review
C로 쉽게 풀어쓴 자료구조
프로그래밍프로젝트 1장 - 2번 (책부록 CD)
Homework 1
[수행 시간 측정] 1부터 n까지의 합을 구하는 프로그램을 다음과 같이 3가지방법으로 알고리즘을 만들어보고 각 알고리즘들을실제로 구현하여 각 알고리즘의 실제수행 시간을 측정하여 이론적인 분석과 같게 나오는지를 조사해보라.
1. 알고리즘 A: sum = n(n + 1)/2공식사용
2. 알고리즘 B: sum = 1 + 2+ … + n
3. 알고리즘 C: sum = (1) + (1 + 1) + (1 + 1 + 1) + …, (1 + 1 + … + 1)
수행 시간측정을 쉽게 하기 위하여 n을 상당히 크게 하고 중간에 고의적인 시간지연함수를 넣거나 같은 합산을 여러 번 반복하라. 각 n값에 대하여 수행 시간을 측정하여 표로 나타내라.
C로 쉽게 풀어쓴 자료구조
실습:수행시간 측정 함수 테스트
수행 시간을 측정하는 전형적인 프로그램 작성해 보세요
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main( void )
{
clock_t start, finish;
double duration;
int n, sum;
printf(“Add up to some number \n Enter a num for n:”);
scanf(“%d”, &n);
start = clock();
sum=n*(n+1)/2;
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf(“sum=%d \n”, sum);
printf("%f 초입니다.\n", duration);
}