나의개발일지
정렬 알고리즘 .in python 본문
정렬 알고리즘
- 정렬이란 데이터를 특정한 기준에 따라 순서대로 나열하는것이다.
- 일반적으로 문제 상황에 따라서 적절한 정렬 알고리즘이 공식처럼 사용한다.
1. 선택 정렬
- 처리되지 않은 데이터 중에서 가장 작은 데이터를 선택해 맨 앞에 있는 데이터와 바꾸는 것을 반폭하는 정렬
- 매번 탐색 범위 만큼 선형탐색한다 2중 반복문으로 구현한다.
- 선택 정렬은 N번 만큼 가장 작은 수를 찾아서 맨 앞으로 보낸다
- 구현 방식에 따라서 사소한 오차는 있을 수 있지만, 전체 연산 횟수는 다음과 같다.
N + (N -1) + (N-2) + … + 2
- 이는 (N^2 + N-2) /2 로 표현할 수 있는데, 빅오 표기법에 의해 O(N^2)이라고 작성한다
선택 정렬 코드
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)
2. 삽입 정렬
- 처리되지 않은 데이터를 하나씩 골라 적절한 위치에 삽입한다
- 선택 정렬에 비해 구현 난이도가 높은편이지만, 일반적으로 더 효율적으로 동작한다
- 삽입 정렬의 시간 복잡도는 O(N^2), 선택 정렬과 마찬가지로 반복문이 두 번 중첩되어 사용
- 삽입 정렬은 현재 리스트의 데이터가 거의 정렬되어 있는 상태라면 매우 빠르게 동작
- 최선의 경우 O(N) = 이미 정렬되어있는 경우
삽입 정렬 코드
array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
for i in range(1,len(array)):
for j in range(i, 0, -1):
if array[j] < array[j-1]:
array[j-1], array[j] = array[j], array[j-1]
print(array, i , j)
else:
print(array)
break
print(array)
3. 퀵 정렬(Quick Sort)
- 기준 데이터를 설정하고 그 기준보다 큰 데이터와 작은 데이터의 위치를 바구는 방법이다.
- 일반적인 상황에서 가장 많이 사용되는 정렬 알고리즘 중 하나이다.
- 병합 정렬과 더불어 대부분의 프로그래밍 언어의 정렬 라이브러리의 근간이 되는 알고리즘이다.
- 가장 기본적인 퀵 정렬은 첫 번째 데이터를 기준 데이터(pivot)로 설정한다.
- 이상적인 경우 분할이 절반씩 일어난다면 전체 연산 횟수 O(NlogN)가 기대된다.
- 하지만 최악의 경우 이미 정렬된 배열일때 O(N^2)의 시간 복잡도가 기대된다.
- 한번 할때마다 왼쪽의 하나뺴고 오른쪽 나머지가 남는다.
퀵정렬 코드
def quick_sort(array, start, end):
if start >= end:
return
pivot = start
left = start + 1
right = end
while(right >= left):
while(left <= end and array[pivot] >= array[left]):
left += 1
while(right > start and array[pivot] <= array[right]):
right -= 1
if (left > right):
array[pivot], array[right] = array[right], array[pivot]
else:
array[left], array[right] = array[right], array[left]
quick_sort(array, start, right-1)
quick_sort(array, right+1, end)
퀵정렬 코드 .in Python (파이썬 라이브러리 이용)
def quick_sort2(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]
print(left_side, "left")
print(right_side, "right")
array = quick_sort2(left_side) + [pivot] + quick_sort2(right_side)
return array
4. 계수 정렬
- 특정한 조건이 부합할 때만 사용할 수 있지만 매우 빠르게 동작하는 정렬 알고리즘
> 계수 정렬은 데이터의 크기 범위가 제한되어 정수 형태로 표현할 수 있을 때 사용 가능
- 데이터의 개수가 N, 데이터(양수) 중 최댓값이 K일때 최악의 경우에도 수행시간 O(N + K)를 보장
pred. 가장 작은 데이터부터 가장 큰 데이터까지의 범위가 모두 담길 수 있도록 리스트를 생성
- 계수 정렬의 시간 복잡도와 공간 복잡도는 모두 O(N + K)
- 계수 정렬은 때에 따라서 심각한 비효율성을 초래할 수 있음
> 데이터가 0과 999,999로 단 2개만 존재하는 경우
- 계수 정렬은 동일한 값을 가지는 데이터가 여러개 등장할 때 효과적으로 사용할 수 있다.
> 성적의 경우 100점을 맞은 학생이 여러 명일 수 있기 때문에 계수 정렬이 효과적
계수 정렬 코드
array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]
count = [0] * (max(array)+1)
for i in range(len(array)):
count[array[i]] += 1
print(count)
for i in range(len(count)):
for j in range(count[i]):
print(i, end=' ')
정렬 알고리즘 비교
정렬 알고리즘 | 평균 시간 복잡도 | 공간 복잡도 | 특징 |
선택 정렬 | O(N^2) | O(N) | 아이디어가 매우 간단하다. |
삽입 정렬 | O(N^2) | O(N) | 데이터가 거의 정렬되어 있을 때는 가장 빠르다. |
퀵 정렬 | O(NlogN) | O(N) | 대부분의 경우에 가장 적합하며, 충분히 빠르다. |
계수 정렬 | O(N + K) | O(N + K) | 데이터의 크기가 한정되어 있는 경우에만 사용이 가능하지만 매우 빠르게 동작한다. |
'언어 > Python' 카테고리의 다른 글
이진탐색 .in Python [백준 5639] (0) | 2023.11.18 |
---|---|
DFS(깊이우선탐색) BFS(너비우선탐색) .in Python [백준1260] (1) | 2023.11.14 |