모두의 알고리즘 with python - QuickSort

1 분 소요

Quick Sort

퀵소트는 ‘그룹을 반으로 나눠서 재귀 호출’하는 방식은 병합 정렬과 다를 바 없지만, 그룹을 나눌 때 미리 기준과 비교해서 나눈다는 점이 다르다!

즉, 먼저 기준과 비교해서 그룹을 나누고, 다음 각각 재귀 호출해서 합치는 방식이라고 할 수 있다.

예시를 잘 못드니 쉬운 코드로 이해도를 높이도록 하자

easyQuickSort.py

# easy quick sort
# input : list a
# output : sorted new List


def quickSort(a):
    n = len(a)
    # 종료 조건 : 정렬할 리스트의 자료 개수가 한 개 이하이면 정렬 X
    if n <= 1:
        return a

    # 기준 값을 정하고 기준에 맞춰 그룹을 나누는 과정
    pivot = a[-1]  # 기준은 자기 마음대로지만, 마지막 값으로 하기로 한다.
    g1 = []  # 기준보다 작은 값을 담을 리스트
    g2 = []  # 기준보다 큰 값을 담을 리스트

    for i in range(0, n - 1):
        if a[i] < pivot:
            g1.append(a[i])
        else:
            g2.append(a[i])

    # 각 그룹에 대해서 재귀 호출로 퀵 정렬을 하고
    # 기준 값과 합쳐 하나의 리스트로 결과값 변환

    return quickSort(g1) + [pivot] + quickSort(g2)  # 더러운데;아무튼 리스트를 이렇게 더할 수 있다.


d = [6, 8, 5, 9, 10, 1, 4, 3, 2, 7]

print(quickSort(d))

이해가 쉽다. 반나눠서 그안에서 기준정하고 또 나누고…의 반복일뿐.

그럼 이제 일반적인 퀵소트 알고리즘을 해보자.

위랑 다른 점은 입력 리스트 안에서 직접 위치를 바꾸며 정렬한다.

normalQuickSort.py

# 리스트 a에서 어디부터 어디까지가 정렬 대상인지
# 범위를 지정하여 정렬하는 재귀 호출 함수

def quickSortSub(a, start, end):

    # 종료 조건
    if end - start <= 0:
        return

    # 기준값
    pivot = a[end]

    i = start

    # 정렬
    for j in range(start, end):
        if a[j] <= pivot:
            a[i], a[j] = a[j], a[i]
            i += 1
    
    a[i], a[end] = a[end], a[i]

    # 재귀 호출
    quickSortSub(a, start, i - 1)
    quickSortSub(a, i + 1, end)



def quickSort(a):
    quickSortSub(a, 0, len(a) - 1)


d = [6, 8, 5, 9, 10, 1, 4, 3, 2, 7]

quickSort(d)

print(d)

이 알고리즘도 계산 복잡도는 역시 O(n*logn)이다.

연습문제

거품정렬의 구현이 연습문제다… 일단 해보자.

BubbleSort.py

def bubbleSort(a):
    n = len(a)

    for i in range(n - 1):
        for j in range(n - i - 1):
            if a[j] > a[j + 1]:
                a[j], a[j + 1] = a[j + 1], a[j]


d = [6, 8, 4, 9, 10, 1, 2, 3, 7, 5]

bubbleSort(d)

print(d)

앞에서부터 하나하나 비교해가는 버블 정렬은 이렇게 for문이 도는 횟수를 주의해서 구현해주면 된다. 간—–단.

댓글남기기