병합정렬 기본개념
.
Coding_test_training(20220220)
[학습자료]
패스트 캠퍼스 “알고리즘 / 기술면접 완전 정복 올인원 패키지 Online.” 강의를 공부하고 정리한 내용입니다.
** URL : https://fastcampus.co.kr/dev_online_algo
[학습내용]
- 병합정렬(merge sort) 개요
문제를 잘개 쪼개는 분할정복 알고리즘을 사용하는 정렬 알고리즘이라고 할 수 있다. memorization을 사용하지는 않는다 따라서 동적계획법을 사용한 알고리즘은 아니다.
- 병합정렬 예시 프로세스
아래와 같은 리스트의 데이터를 정렬한다고 가정하자
test_data = [2,8,5,4]
STEP 1) 먼저 [2,8],[5,4]로 짜른다.
STEP 2) [2,8]을 다시 [2],[8]로 짜른다.
STEP 3) [2]와 [8]을 정렬해서 합친다. 그러면 [2,8]이 된다.
STEP 4) [5,4]를 [5],[4]로 짜른다.
STEP 5) [5]와 [4]을 정렬해서 합친다. 그러면 [4,5]가 된다.
STEP 6) [2,8]과 [4,5]를 합친다.
step 6-1) 2보다 4가 크기 때문에 [2]
step 6-2) 8이 4보다 크기 때문에 [2,4]
step 6-3) 8이 5보다 크기 때문에 [2,4,5]
step 6-4) 남은거는 8밖에 없으니 [2,4,5,8]
- 실제 코드로 구현해보기
병합정렬은 함수 두개로 구현을 한다.
함수 1. 메인함수 겸 재귀용법으로 데이터를 쪼개는 함수
함수 2. 나누어진 데이터를 병합하는 함수
# 함수 1. 메인함수 겸 재귀용법으로 데이터를 쪼개는 함수
def merge_sort(data):
if len(data) <= 1:
return data
medium = int(len(data) / 2)
left = merge_sort(data[:medium])
right = merge_sort(data[medium:])
return merge(left, right)
#함수 2. 나누어진 데이터를 병합하는 함수
def merge(left, right):
merged_result = list()
left_index, right_index = 0, 0
# case1 : left/right 둘다 있을때
while (len(left) > left_index) and (len(right) > right_index):
if left[left_index] > right[right_index]:
merged_result.append(right[right_index])
right_index += 1
else:
merged_result.append(left[left_index])
left_index += 1
# case2 : left 데이터만 남아있을때
while len(left) > left_index:
merged_result.append(left[left_index])
left_index += 1
# case3 : right 데이터만 남아있을때
while len(right) > right_index:
merged_result.append(right[right_index])
right_index += 1
return merged_result
test_data = [2,8,5,4]
merge_sort(test_data)
[2,4,5,8]
- 시간복잡도
가지치기한 각 단계별로는 각각 O(n)인데 이게 log2의 n개 만큼 만들어지기 때문에 결론적으로는 O(n log n)
삽입정렬, 선택정렬보다는 빠른 시간복잡도를 보인다.