프로그래밍을 배우다 보면 알고리즘의 시간 복잡도라는 개념을 자주 접하게 됩니다.
시간 복잡도는 알고리즘이 문제를 해결하는 데 걸리는 시간의 양을 측정하는 방법으로, 알고리즘의 효율성을 평가하는 중요한 지표입니다. 이번 포스트에서는 시간 복잡도를 쉽게 이해할 수 있도록, 다양한 시간 복잡도의 예시를 소개하고 그 의미를 설명하겠습니다.
1. 시간 복잡도란?
시간 복잡도는 알고리즘이 문제를 해결하는 데 걸리는 시간의 양을 나타내는 측정 방법입니다.
입력 크기(n)가 커질수록 알고리즘이 소요하는 시간이 어떻게 변화하는지를 분석하는 데 사용됩니다. 가장 흔히 사용하는 표기법은 빅오 표기법(Big O Notation)입니다.
2. 주요 시간 복잡도와 예시
O(1) - 상수 시간 알고리즘
O(1) 알고리즘은 입력 크기와 관계없이 일정한 시간이 소요되는 알고리즘을 말합니다. 즉, 데이터의 양이 늘어나도 처리 시간은 변하지 않습니다.
예시
def print_first(my_list):
print(my_list[0])
이 함수는 리스트의 첫 번째 요소를 출력하는데, 리스트의 크기와 상관없이 항상 한 번의 작업만 필요하므로 시간 복잡도는 O(1)입니다.
O(n) - 선형 시간 알고리즘
O(n) 알고리즘은 입력 크기와 실행 시간이 비례하는 경우를 말합니다. 입력 크기가 두 배로 늘어나면 실행 시간도 두 배로 증가합니다.(반복문)
예시 1
def print_each(my_list):
for i in range(len(my_list)):
print(my_list[i])
이 함수는 리스트의 모든 요소를 순회하여 출력합니다. 리스트의 크기가 n이라면 n번 반복되므로 시간 복잡도는 O(n)입니다.
예시 2
def print_half(my_list):
for i in range(len(my_list) // 2):
print(my_list[i])
이 함수는 리스트의 앞 반쪽만을 출력합니다. 반복 횟수는 n/2이지만 상수 계수는 무시하므로 시간 복잡도는 O(n)입니다.
예시 3
def print_each_three_times(my_list):
for i in range(len(my_list)):
print(my_list[i])
for i in range(len(my_list)):
print(my_list[i])
for i in range(len(my_list)):
print(my_list[i])
이 함수는 리스트의 각 요소를 세 번 출력합니다. 각 반복문이 O(n)만큼 실행되지만, 계수를 무시하면 전체 시간 복잡도는 O(n)입니다.
O(n^2) - 이차 시간 알고리즘
O(n^2) 알고리즘은 반복문이 중첩되어 있을 때 발생하는 시간 복잡도입니다. 즉, 두 개의 중첩된 반복문이 있을 때 사용됩니다.
예시
def print_pairs(my_list):
for i in range(len(my_list)):
for j in range(len(my_list)):
print(my_list[i], my_list[j])
이 함수는 리스트의 모든 쌍을 출력합니다. 두 개의 반복문이 각각 n번 반복되므로 시간 복잡도는 O(n^2)입니다.
O(log n) - 로그 시간 알고리즘
O(log n) 알고리즘은 입력 크기가 두 배로 증가할 때 반복 횟수가 일정 비율로 증가하는 알고리즘입니다. 일반적으로 이진 탐색에서 볼 수 있습니다.
예시
def binary_search(my_element, my_list):
start_index = 0
end_index = len(my_list) - 1
while start_index <= end_index:
midpoint = (start_index + end_index) // 2
if my_list[midpoint] == my_element:
return midpoint
elif my_element < my_list[midpoint]:
end_index = midpoint - 1
else:
start_index = midpoint + 1
return None
이 함수는 정렬된 리스트에서 특정 요소를 찾기 위해 검색 범위를 반으로 줄여 나갑니다. 최대 반복 횟수는 로그 함수에 비례하므로 시간 복잡도는 O(log n)입니다.
O(n log n) - 선형 로그 시간 알고리즘
O(n log n) 알고리즘은 선형 시간 알고리즘이 로그 시간 알고리즘을 반복할 때 발생합니다. 주로 효율적인 정렬 알고리즘에서 볼 수 있습니다.
예시
def print_one_to_n(my_list):
n = len(my_list)
for i in range(1, n+1):
print(binary_search(i, my_list))
def binary_search(my_element, my_list):
start_index = 0
end_index = len(my_list) - 1
while start_index <= end_index:
midpoint = (start_index + end_index) // 2
if my_list[midpoint] == my_element:
return midpoint
elif my_element < my_list[midpoint]:
end_index = midpoint - 1
else:
start_index = midpoint + 1
return None
이 함수는 binary_search를 n번 호출합니다. 각 호출의 시간 복잡도는 O(log n)이므로 전체 시간 복잡도는 O(n log n)입니다.
3. 시간 복잡도 비교
시간 복잡도는 알고리즘의 효율성을 평가하는 중요한 지표입니다. 시간 복잡도가 낮을수록 입력 크기가 커져도 알고리즘이 더 빨리 실행됩니다. 일반적인 시간 복잡도는 다음과 같이 비교할 수 있습니다
O(1) < O(log n) < O(n) < O(n log n) < O(n^2)
시간 복잡도가 낮은 알고리즘을 사용하는 것이 성능이 좋으며, 문제를 해결하는 데 필요한 시간을 줄일 수 있습니다.
결론
시간 복잡도는 알고리즘의 성능을 평가하는 데 중요한 개념입니다.
다양한 시간 복잡도를 이해하고, 적절한 알고리즘을 선택하는 것이 효율적인 프로그래밍을 위한 핵심입니다.
이번 포스트를 통해 시간 복잡도의 기본 개념과 주요 예시를 쉽게 이해하시길 바랍니다!
공감과 댓글은 저에게 큰 힘이 됩니다.
Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.
'Algorithms > Study' 카테고리의 다른 글
알고리즘의 공간 복잡도, 팰린드롬 문제로 초보자도 쉽게 이해하자 (0) | 2024.08.19 |
---|---|
파이썬 내장 함수와 메소드의 시간 복잡도 (0) | 2024.08.19 |
선형 탐색 시간 분석하기: 효율적인 알고리즘의 중요성[파이썬] (2) | 2024.08.17 |
알고리즘의 중요성과 컴퓨터 성능 업그레이드 중 누가 이길까? (0) | 2024.08.17 |
점근 표기법으로 보는 알고리즘: 어떤 알고리즘이 좋을까? (0) | 2024.08.17 |