정렬 간단 정리
정렬이란 데이터를 특정한 기준에 따라서 순서대로 나열하는 것이다.
이 책 '이것이 취업을 위한 코딩테스트다.'에서는
- 선택 정렬
- 삽입 정렬
- 퀵 정렬
- 계수 정렬
총 4가지를 소개하고 있다.
선택 정렬
이 방법은 가장 원시적인 방법인데, 매번 가장 작은 것을 선택한다는 의미에서 선택정렬이라고 한다.
무작위로 있는 데이터를 오름차순으로 정렬하고자 할 때, 가장 작은 것을 선택하여 앞으로 보내는 알고리즘을 수행하는 알고리즘이다.
array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
for i in range(len(array)):
min_index = i
for j in range(i+1, len(array)):
if array[min_index] > array[j]:
min_index = j
array[i], array[min_index] = array[min_index], array[i] #스와프
print(array)
선택정렬은 N(N+1)번의 연산을 하므로 빅오 표기법에 따라
선택정렬의 시간 복잡도는 O(N^2)이다.
삽입 정렬
삽입정렬은 특정한 데이터가 들어가기 이전에, 그 앞까지의 데이터는 이미 정렬되어있다고 가정하고 정렬된 데이터 리스트에서 적절한 위치를 찾은 후에 삽입하는 것이 특징이다.
삽입정렬은 필요할 때만 위치를 바꾸므로 데이터가 저의 정렬되어있을떄 특히 빠른 알고리즘이다.
array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
for i in range(len(array)):
for j in range(i, 0, -1):
if array[j] <array[j-1]: #한칸씩 왼쪽으로 이동
array[j], array[j-1] = array[j-1], array[j]
else: #자신보다 더 작은 수를 만나면 그 위치에서 멈춤
break
print(array)
삽입정렬의 기본 시간복잡도는 O(N^2)이지만 거의정렬되어있던 경우, 최선의 경우에서는 O(N)을 따른다.
퀵 정렬
퀵정렬은 가장 많이 사용되는데, 피벗을 정하고 그 기준보다 큰데이터와 작은데이터의 위치를 바꾸는 알고리즘이다.
(왼쪽에서는 피벗보다 큰 수를 찾고, 오른쪽에서는 피벗보다 큰 수를 찾아 그 둘의 위치를 변경해줌하고나서는 피벗을 파티션으로 삼아 재귀함수를 통해 똑같은 방법으로 정렬될때까지 시행한다.)
array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
def quick_sort(array):
if len(array) <= 1:
return array
pivot = array[0] #피벗은 첫번째 원소
tail = array[1:] #피벗을 제외한 리스트
left_side = [x for x in tail if x <= pivot]#분할된 왼쪽
right_side = [x for x in tail if x > pivot]#분할 된 오른쪽
#분할 후 왼쪽 오른쪽 각각 수행 후 전체리스트 반환
return quick_sort(left_side) + [pivot] + quick_sort(right_side)
print(quick_sort(array))
퀵정렬의 시간 복잡도는 평균적으로는 O(NlogN)이나, 이미 데이터가 정렬되어있는 겨우 즉, 최악의 경우에는 O(N^2)로 매우 느리게 동작하므로 주의 해야한다.
계수 정렬
게수정렬 알고리즘은 특정한 조건이 부합될 경우만 사용할 수 있는데 바로 아래의 조건이다.
데이터의 크기 범위가 제한되어 정수 형태로 표현 할 수 있을때
이유는 계수 정렬이 모든 범위를 담을 수 있는 리스트(배열)을 선언해야 하기 때문이다. 만약 데이터의 값이 무한란 범위를 받아 가장 큰 데이터와 가장 작은 데이터의 차이가 너무 크다면 쓸모없이 너무 큰 리스트(배열)을 선언해야하기 때문이다.
따라서 위와 같은 조건을 충족 할 대에 한해 계수정렬은 데이터가 많더라도 빠르게 동작한다.
먼저 계수정렬을 위해 가장 큰 데이터와 가장 작은 데이터의 범위가 모두 담길 수 있도록 하나의 리스트를 생성한다. 처음에는 리스트의 모든 데이터를 0으로 초기화한다. 그 다음 데이터를 하나씩 확인하며 데이터와 동일한 인덱스의 데이터를 1씩 증가시키면 된다.
#모든 원소의 값이 0보다 크거나 같다고 가정
array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]
#모든 범위를 포함하는 리스트 선언(모든 값은 0으로 초기화)
count = [0] * (max(array) + 1)
for i in range(len(array)):
count[array[i]] += 1
for i in range(len(count)):#리스트에 기록된 정렬 정보 확인
for j in range(count[i]):
print(i, end=' ') #띄어쓰기를 구분으로 등장한 횟수만큼 출력
계수 정렬의 시간복잡도는 O(N+K)이다.
라이브러리
기본 정렬 라이브러리인 sorted()함수나 sort(), 또는 람다 함수를 사용하는 방법도 있다.
정렬 라이브러리 같은 경우 최악의 경우에도 O(NlogN)을 보장한다,
'Algorithm > 이것이 취업을 위한 코딩테스트다' 카테고리의 다른 글
(유형별 기출/그리디) 곱하기 혹은 더하기 (0) | 2023.05.25 |
---|---|
(유형별 기출/그리디) 모험가 길드 (0) | 2023.05.25 |
특정 거리의 도시 찾기 (DFS,BFS/백준 18352번) (0) | 2023.04.21 |
미로 탈출 (DFS,BFS/실전) (0) | 2023.04.20 |
음료수 얼려 먹기(DFS.BFS/실전) (0) | 2023.04.19 |