전체 글 (115)

08
05

시간 복잡도를 계산 하는데 순차 탐색 알고리즘과 이진 탐색 알고리즘을 사용한다.

 


#1 순차 탐색 알고리즘

for(i=0; i<len; i++)
{
	if(ar[i] == target)
    	return i; //찾은 대상의 인덱스 값 반환
}

이 코드는 순차 탐색 알고리즘을 구현한것이다.

이를 토대로 시간 복잡도를 분석해 데이터의 수 n에 대한 연산횟수의 함수 T(n)을 구해보자

우선 이 알고리즘에 사용된 연산자는 <+, ==이렇게 세개다.

이 중에서 == 연산을 적게 수행해야 좋은 알고리즘이다.
이유는 비교연산 == 이 줄어야 < 연산과 ++ 연산의 수행횟수도 줄어들기 때문이다.

다시말해 다른 연산들은 == 연산에 의존적이다

이렇게 알고리즘의 시간 복잡도를 계산하기 위해서는 핵심 연산을 찾아야한다.
그 핵심 연산 중심으로 시간 복잡도를 계산해야한다.

어쨋든 이제 위에 코드로 순차 탐색 알고리즘 느낌을 알 수 있다.
순차 탐색 알고리즘은 리스트에서 찾고자 하는 값을 맨 앞에서부터 끝까지
차례대로 하나씩 찾아 나가는 것이다

그렇기 때문에 만약 찾고자 하는 값이 맨 앞에 있으면 수행횟수는 1이지만
맨 마지막에 있으면 수행횟수는 데이터의 수 n이 된다.
이 때 각각의 경우를 '최선의 경우', '최악의 경우'라 한다.


알고리즘의 성능을 평가를 할 땐 '평균적인 경우'를 따지는게 좋겠지만
'평균적인 경우'의 조건과 상황을 정확하게 알기는 힘들기 때문에 일반적으로는 '최악의 경우'로 따진다고 한다.

 

이제 최악의 경우를 계산 해보자

'데이터의 수가 n개일 때, 최악의 경우에 해당하는 연산횟수는(== 횟수) n이다'

즉 '데이터 수 n에 대한 연산횟수의 함수 T(n)'은 다음과 같다

T(n) = n


#2 이진 탐색 알고리즘

이진 탐색 알고리즘은 다음의 조건을 만족해야만 한다

'배열에 저장된 데이터는 정렬되어 있어야한다'

 

원리는 간단하다

0 1 3 5 14 20 27
index 0 index 1 index 2 index 3 index 4 index 5 index 6

위 표의 정렬된 배열을 arr이라 가정하고

 

이 배열에서 숫자 1이 들어있는지 확인하기 위해

 

이진 탐색 알고리즘을 적용해보자

 

이진 탐색의 첫번째 시도

1, 배열 인덱스의 시작과 끝은 index 0과 index 6이다

2, 0과 6을 합하여 그 결과를 2로 나눈다(절반으로 나누기)

3, 나눈 결과는 3이다

4, 위 배열의 arr[3]에 저장된 값이 1인지 확인한다.

 

그러나 arr[3]은 5였기 때문에 두번째 시도를 한다

1, arr[3]에 저장된 값 5와 탐색 대상인 1의 대소를 비교한다

2, arr[3] > 1이므로 탐색 범위를 arr[3]를 기준으로 인덱스를 0~2로 제한한다

3, 0 + 2를 하여 그 결과를 2로 나눈다. 이때 나머지는 버린다

4, 2로 나눠서 1이 나오므로 arr[1]의 값이 1인지 확인한다

 

두번의 시도로 대상을 찾았다.

확실히 빠르지만 정렬되어 있어야 한다는 조건이 있다.

위의 과정을 반복하는 것이 이진 탐색 알고리즘이다.

절반으로 나눌 때마다 탐색의 대상이 반으로 줄어든다는 특징이 있다.

 

그런데 절반으로 나누다가 시작과 끝의 인덱스가 만나면 어떤 의미일까?

만난다(겹친다)는 아직 탐색의 대상이 하나 남았다는 뜻이다.

 

즉, 두 인덱스가 겹친다 하더라고 탐색이 끝난것은 아니다.

그러므로 기본적인 이진 탐색 알고리즘은 다음과 같은 형태일 것이다.

int first = 0;
int last = len - 1;
int mid;

while(first <= last) //아니면 first < last 이거나 last > first 여야함
{
    int target = 1;
	//이진 탐색 알고리즘 진행
    mid = (first + last) / 2; //탐색 대상의 중앙 인덱스 값
    
    if(target == arr[mid]) //탐색 대상 찾음
        return mid;
    else //못찾으면 다시 반으로 줄이기 
    {
        if(target < arr[mid]) //대소비교
            last = mid - 1;
        else
            first = mid + 1;
    }
}

만나는 인덱스까지 탐색했다는건 탐색에 실패했다는 뜻이기도하다.

 

그런데 코드에서

        if(target < arr[mid]) //대소비교
            last = mid - 1;
        else
            first = mid + 1;

이부분은 왜 mid의 인덱스값이 아닌 -1과 +1을 하였을까?

대소 비교를 하여 대상이 절반 인덱스로부터 왼쪽에 있는지 오른쪽에 있는지 확인을 하면 절반 인덱스는 다음 탐색에서 제외해야한다.

 

절반 인덱스를 제외하지않는다면 무한루프에 걸려 계속 탐색할 것이다.


#2 - 1 이진 탐색 알고리즘 최악의 경우의 '시간 복잡도'

 

그렇다면 위의 이진 탐색 알고리즘 코드에서

 

"데이터 수가 n개일 때, 최악의 경우에서 발생하는 비교연산의 횟수는 어떻게 될까?"

 

데이터 수 반으로 줄여 n/2개에서 비교 연산 1번

데이터 수 반으로 줄여 n/4개에서 비교 연산 1번

데이터 수 반으로 줄여 n/8개에서 비교 연산 1번

 

n이 몇개인지 모르기 때문에 정확히 몇번이라고 답하기엔 힘들다.

 

그래서 수학으로 이것을 나타내보도록하자

 

  • 8이 1이되기까지 2로 나눈횟수 3회 => 비교연산 3회
  • 1인 상태에서 비교연산 한번 더 => 비교연산 1

이것을 일반화시키면

  • n이 1이되기까지 2로 나눈횟수 k회 => 비교연산 k회
  • 1인 상태에서 비교연산 한번 더 => 비교연산 1

따라서 최악의 경우에 대한 시간 복잡도 함수는 T(n) = k+1 이 된다.

 

그러나 아직 끝이 아니다. 우리는 k를 구해야한다.

 

n을 k회만큼 2로 나누기 때문에 다음과 같이 나타낼 수 있다

이 식을 정리 하면 

이제 로그를 취해보면

최악의 경우에 대한 시간 복잡도 함수는 T(n) = k+1 즉, 위의 식의 k를 대입하면

 

그런데 k+1에서 +1은 어디갔을까?

함수를 구한 이유는 "비교연산의 횟수가 로그적으로 증가한다"는 분석을 얻기 위함이다.

데이터 수가 증가함에 따라 변화의 정도를 분석하기 윈한것이므로 +1은 중요하지않다.

COMMENT
 
08
05

알고리즘 성능은 어케 분석하는가

 

#1 알고리즘 평가요소

우선 알고리즘을 평가하는 두가지 요소는 다음과 같다.

- 어떠한 알고리즘이 어떠한 상황에서 더 빠르고 더 느린가

- 어떠한 알고리즘이 어떠한 상황에서 메모리를 더 적게 더 많게  쓰는가

 

즉 '속도'와 '메모리 사용량'으로 평가하는데 

 

'속도'에 해당하는 알고리즘의 수행시간 분석결과를 '시간복잡도'라 한다. ( Time Complexity )

'메모리 사용량'에 대한 분석결과를 '공간복잡도'라 한다. ( Space Complexity )

 

일반적으로 알고리즘 평가할 때 중요도는

실행 '속도' > '메모리 사용량' 으로 속도에 관심을 더 둔다.

 

그럼 '속도'를 어떻게 측정하는가


#2 알고리즘 수행속도 평가방법

- 연산횟수를 센다.

- 처리해야할 데이터의 수 n에 대한 연산횟수의 함수 T(n)을 구성한다.

 

이때 당연히 연산횟수가 적어야 빠른 알고리즘이다.

 

그리고 함수 T(n)을 구성하는 이유는

데이터 수의 증가에 따른 연산횟수의 변화 정도를 판단할 수 있기 때문이다.

 

함수T(n)으로 구성하면 표든 그래프든 변화 정도를 한눈에 파악할 수 있다.

이는 둘 이상의 알고리즘을 비교하기가 용이해진다는 장점이 있다.

알고리즘을 서로 비교하기 쉬워짐

COMMENT
 
08
05

#1 자료구조 기본적 이해

프로그램이란 '데이터를 표현'하고, 그렇게 표현된 '데이터를 처리'하는 것이다.

 

'데이터 표현'은 '데이터 저장'이며 이를 담당하는 것이 자료구조다.

'데이터를 처리'는 알고리즘이 저장된 데이터를 대상으로 '문제의 해결 방법'을 뜻한다.

 

그냥 쉽게 말해 데이터를 담는 구조를 다루는 학문이라고보면된다.

 

[자료구조의 분류표]

선형구조 리스트 비선형구조 트리
스택 그래프
 
파일구조 순차파일 단순구조 정수
색인파일 실수
직접파일 문자, 문자열

 

COMMENT