Sorting 알고리즘 기초개념 및 구현실습
.
그림, 실습코드 등 학습자료 출처 : https://github.com/ythwork
1) 참고사이트 : https://github.com/ythwork
2) 참고서적 : Hello Coding 그림으로 개념을 이해하는 알고리즘 (아디트야 바르가바 지음, 김도형 옮김 / 한빛미디어)
1. Quick Sort (퀵정렬)
- 현업에서 많이 사용되는 빠른 정렬 기법
1) 분할정복기법 (Divide and conquer)을 활용한다.
(문제를 분할하여 해결, 재귀 함수를 이용)
기준값을 하나 택하고 순회를 돌면서 기준값보다 작은 데이터는 좌측에, 기준값보다 큰 데이터는 우측으로 분할하고 다시 퀵 정렬을 적용한다.
2) 통상 \(\ O(nlogn)\)이고, 이미 정렬 된 데이터의 경우(최악의 경우) \(\ O(n^2)\) 를 보이기도 한다.
퀵소트의 경우 이미 정렬 된 데이터에 대해서 최악의 효율을 보입니다. 피벗이 한쪽 끝으로 오게 되어서 파티션을 나눌 때 균형이 완전히 무너지고 한 번 정렬에 데이터가 하나씩 떨어져 나가게 됩니다. 따라서 데이터가 n개라면 n과 거의 동일한 수의 단계를 거쳐야 합니다. 그래서 결과적으로 이미 정렬 된 데이터에 대해 효율은 \(\ O(n^2)\)이 됩니다.
3) 작동원리
입력 : [7,5,3,5,4,2,8]
출력 : [2,3,4,5,5,7,8]
4) 파이썬 코드구현
import random
def get_pivot_index(li, start, mid, end):
idx_li=[start, mid, end]
if li[idx_li[0]] > li[idx_li[1]]:
idx_li[0], idx_li[1]=idx_li[1], idx_li[0]
if li[idx_li[1]] > li[idx_li[2]]:
idx_li[1], idx_li[2]=idx_li[2], idx_li[1]
if li[idx_li[0]] > li[idx_li[1]]:
idx_li[0], idx_li[1]=idx_li[1], idx_li[0]
return idx_li[1]
def quick_sort(li, start, end):
if start >= end:
return
left=start
right=end
mid=(start+end)//2
pivot_idx=get_pivot_index(li, start, mid, end)
li[mid], li[pivot_idx]=li[pivot_idx], li[mid]
pivot=li[mid]
while left <= right:
while li[left] < pivot:
left+=1
while li[right] > pivot:
right-=1
if left <= right:
li[left], li[right]=li[right], li[left]
left+=1
right-=1
quick_sort(li, start, right)
quick_sort(li, left, end)
if __name__=="__main__":
data=[7,5,3,5,4,2,8]
print("input : ", data)
quick_sort(data, 0, len(data)-1)
print("output : ", data)
input : [7, 5, 3, 5, 4, 2, 8]
output : [2, 3, 4, 5, 5, 7, 8]
- 빅오계산
2. Bubble Sort (거품정렬)
-
서로 인접한 두 원소를 검사하여 정렬하는 알고리즘
-
인접한 2개의 레코드를 비교하여 크기가 순서대로 되어 있지 않으면 서로 교환한다.
-
구현하기 쉬운 것이 특징이다.
-
작동원리
입력 : [7,2,4,9]
출력 : [2,4,7,9]
- 파이썬 코드 구현
import random
def bubble_sort(li):
n=len(li)
for i in range(n-1):
for j in range(n-i-1):
if li[j] > li[j+1]:
li[j], li[j+1]=li[j+1], li[j]
if __name__=="__main__":
data=[7,2,4,9]
print("input : ",data)
bubble_sort(data)
print("output : ", data)
input : [7, 2, 4, 9]
output : [2, 4, 7, 9]
- 빅오계산
데이터 개수가 4개일때
7 9 비교 ,2 9 비교, 4 9비교 3번
7 2 비교, 7 4 비교 2번
2 4 비교 1번
총 6번 비교
등차수열로 늘어나게 되므로 빅오는 O(n제곱) 이다.
다시말해 데이터가 많아질수록 엄청나게 늘어나게 된다.
3. Selection Sort (선택정렬)
-
빅오 : \(\ O(n^2)\)
-
최소값을 선택하는 과정을 반복해서 선택 정렬이라 부른다고 한다.
step1) 주어진 리스트 중에 최솟값을 찾는다.
step2) 그 값을 맨 앞에 위치한 값과 교체한다.
step3) 맨 처음 위치를 뺀 나머지 리스트를 같은 방법으로 교체한다.
- 파이썬 코드구현
import random
def findSmallest(li):
smallest = li[0]
smallest_index = 0
for idx in range(1,len(li)):
if li[idx] < smallest:
smallest = li[idx]
smallest_index = idx
return smallest_index
def selectionSort(li):
result = []
for count in range(len(li)):
smallest = findSmallest(li)
result.append(li.pop(smallest))
return print("정렬 후 리스트 :", result)
li = [random.randint(1,10000) for data in range(10)]
print("정렬 전 최초 리스트 :", li )
selectionSort(li)
정렬 전 최초 리스트 : [9382, 1201, 6871, 7670, 2424, 2215, 11, 157, 4188, 9456]
정렬 후 리스트 : [11, 157, 1201, 2215, 2424, 4188, 6871, 7670, 9382, 9456]