위의 식처럼 데이터가 30,000개나 되는 요소는 약 450,000,000회의 비교 연산을 거쳐야 한다.
def bubblesort(data):
for i in range(len(data) - 1):
for j in range(len(data) - i - 1):
if data[j] > data[j + 1]:
data[j], data[j + 1] = data[j + 1], data[j]
삽입 정렬은 자료구조가 정렬되어 있다면 한번도 비교를 거치지 않는다
두개의 평균이 (n^2 + n -2) / 2 회 정도
삽입 정렬시 30000개의 데이터 일때 평균 비교 횟수로 계산한다면 225,007,499회 이다.
def insertionSort(data):
for i in range(1, len(data)):
for j in range(i, 0, -1):
if data[j - 1] > data[j]:
data[j - 1], data[j] = data[j], data[j - 1]
💡 동작 과정을 한마디로 요약하면 기준 요소 선정 및 분할의 반복
링크드 리스트에서는 노드 삽입이 간단하지만 배열 요소 사이에서는 새로운 요소를 삽입하려면 다른 요소를 이동해야 하는데 큰 오버헤드 발생
def quick_sort(array, start, end):
if start >= end: # 원소가 1개인 경우 종료
return
pivot = start # 피벗은 첫 번째 원소
left = start + 1
right = end
while(left <= right):
# 피벗보다 큰 데이터를 찾을 때까지 반복
while(left <= end and array[left] <= array[pivot]):
left += 1
# 피벗보다 작은 데이터를 찾을 때까지 반복
while(right > start and array[right] >= array[pivot]):
right -= 1
if(left > right): # 엇갈렸다면 작은 데이터와 피벗을 교체
array[right], array[pivot] = array[pivot], array[right]
else: # 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체
array[left], array[right] = array[right], array[left]
# 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행
quick_sort(array, start, right - 1)
quick_sort(array, right + 1, end)
# 파이썬을 장점을 활용한 퀵정렬
def quickSort(array):
if len(array) <= 1:
return array
pivot = array[0]
tail = array[1:]
leftSide = [x for x in tail if x <= pivot]
rightSide = [x for x in tail if x > pivot]
return quickSort(leftSide) + [pivot] + quickSort(rightSide)
기준 요소 선정과 분할의 반복으로 동작한다.
자료구조의 크기가 n일 때 퀵정렬의 재귀 호출의 깊이는 logN이다
재귀 호출의 깊이 * 각 재귀 호출 단계에서의 비교 횟수
N * logN = NlogN
30000개를 비교할 때 446180 번만에 비교를 수행해서 정렬이 된다.
최악의 경우
재귀 호출마다 자료 구조 분할이 1 : n-1 로 이루어 지는 것
💡 퀵 정렬은 평균적으로 1.39nlogn회 비교를 수행한다. 최선의 경우 보다 39퍼 정도 느린 성능인 수치