great_park
great_park
great_park
전체 방문자
오늘
어제
06-09 07:11
  • 분류 전체보기 (124)
    • Computer Science (48)
      • Database (9)
      • Operating System (8)
      • Computer Network (0)
      • Computer Architecture (9)
      • Cloud computing (9)
      • Algorithm (13)
    • Algorithm PS (62)
      • DFS & BFS (21)
      • Floyd-Warshall (1)
      • Dijkstra (0)
      • Divide and Conquer (0)
      • Dynamic Programing (22)
      • Greedy (0)
      • BackTracking (11)
      • Binary Search (6)
      • Brute Force (0)
      • Sorting (0)
      • Stack & Queue (1)
      • Number Theory (0)
    • 기타 (12)
      • AWS (3)
      • Docker (1)
      • 기타 (8)
    • 2023 Google Solution Challenge (1)

최근 글

인기 글

블로그 메뉴

  • 홈
  • 태그
  • 방명록
반응형

태그

  • 알고리즘
  • dp
  • Database
  • Docker
  • php
  • operating system
  • LIS
  • DeadLock
  • BOJ
  • dfs
  • BFS
  • Binarysearch
  • Node.js
  • Single-Cycle Datapath
  • mysql
  • backtracking
  • Binary Search
  • cloud computing
  • Computer Architecture
  • pub/sub
hELLO · Designed By 정상우.
great_park

great_park

Computer Science/Algorithm

[Algorithm] 퀵 정렬(Quick sort) 알고리즘

2023. 1. 19. 21:08
반응형

Quick sort

Idea

퀵 정렬은 기본적으로 분할 정복 (Devide and Conquer) 기법과 재귀를 이용한 정렬 알고리즘입니다. Pivot이라는 것을 사용하여 정렬의 기준을 정하게 됩니다. 그리고 그 pivot을 기준으로 “작은 group”, “큰 group”을 나누고, 분할 정복 기법을 이용하여 각각을 해결하는 방식입니다.

6 1 5 11 16 [7] 10 13

위와 같은 숫자 배열을 정렬하고자 할 때, 아무 값이나 pivot으로 선정합니다. 저는 7을 선정하였습니다. pivot을 선정하면, 해당 pivot을 기준으로 작은 값들과 큰 값들을 분류하여 각각 왼쪽, 오른쪽에 위치시킵니다.

6 1 5 [7] 11 16 10 13

그럼, [6,1,5]는 작은 group, [11,16,10,13]은 큰 group이 됩니다. 그럼, 7이라는 pivot은 이제 위치가 고정되게 됩니다. 즉, 정렬이 완료된 것이죠.

이제 각 group에서 pivot을 다시 선정하고, 똑같이 pivot을 기준으로 group을 나눕니다.

작은 group: 임의로 5을 pivot으로 선정

6 1 [5] -> 1 [5] 6
큰 group: 임의로 13을 pivot으로 선정
11 16 10 [13] -> 11 10 [13] 16

여기서 잠시 중간 점검을 하면 아래와 같습니다.

1 5 6 7 11 10 13 16

그럼, 1-5-6-7 까지는 정렬이 완료된 것을 볼 수 있습니다. 이는, 작은 group에서 더 이상 sub problem으로 분할할 수 없기 때문입니다.

과정을 정리하면 아래와 같습니다.

  1. pivot을 정한다.
  2. pivot보다 큰 값은 오른쪽에, pivot보다 작은 값은 왼쪽에 둔다.
  3. pivot을 기준으로 작은 group, 큰 group을 다시 1번 과정부터 더 이상 분할할 수 없을 때까지반복한다.

 

Code (재귀 사용) - 비효율적

def quick_sort(arr):
    if len(arr) <= 1: # 더 이상 분할할 수 없는 경우
        return arr

    pivot = arr[len(arr) // 2]
    lesser_arr, equal_arr, greater_arr = [], [], []

    for num in arr:
        if num < pivot:
            lesser_arr.append(num)
        elif num > pivot:
            greater_arr.append(num)
        else:
            equal_arr.append(num)

		# 각 group에 대해 재귀 호출
    return quick_sort(lesser_arr) + equal_arr + quick_sort(greater_arr) 

 

Code (partition) - 효율적

def quick_sort(arr):
    def sort(low, high):
        if high <= low:
            return

        mid = partition(low, high)
        sort(low, mid - 1)
        sort(mid, high)

    def partition(low, high):
        pivot = arr[(low + high) // 2]
        while low <= high:
            while arr[low] < pivot:
                low += 1
            while arr[high] > pivot:
                high -= 1
            if low <= high:
                arr[low], arr[high] = arr[high], arr[low]
                low, high = low + 1, high - 1
        return low

    return sort(0, len(arr) - 1)

 

Time complexity

  • 쿽 정렬의 성능은 pivot 값을 어떻게 선택하느냐에 크게 달라질 수 있습니다.
  • Best Case: pivot 값을 기준으로 동일한 개수의 작은 값들과 큰 값들이 분할되는 경우 → O(nlog(n))의 시간 복잡도를 가진다.
  • Worst Case: pivot 값을 기준으로 분할했을 때 값들이 한 편으로 크게 치우는 경우 → O(n^2)의 시간 복잡도를 가진다.
반응형
저작자표시 (새창열림)

'Computer Science > Algorithm' 카테고리의 다른 글

[Algorithm] 위상 정렬(Topological sort) 알고리즘  (0) 2023.01.28
[Algorithm] 힙 정렬(Heap sort) 알고리즘  (0) 2023.01.28
[Algorithm] 계수 정렬(Counting sort) 알고리즘  (0) 2023.01.27
[Algorithm] 합병 정렬(merge sort) 알고리즘  (0) 2023.01.23
[Algorithm] 선택 정렬, 버블 정렬, 삽입 정렬 알고리즘  (0) 2023.01.19
    'Computer Science/Algorithm' 카테고리의 다른 글
    • [Algorithm] 힙 정렬(Heap sort) 알고리즘
    • [Algorithm] 계수 정렬(Counting sort) 알고리즘
    • [Algorithm] 합병 정렬(merge sort) 알고리즘
    • [Algorithm] 선택 정렬, 버블 정렬, 삽입 정렬 알고리즘
    great_park
    great_park
    GitHub : https://github.com/great-park

    티스토리툴바