Skip to content

Latest commit

ย 

History

History
390 lines (297 loc) ยท 12.3 KB

sorting.md

File metadata and controls

390 lines (297 loc) ยท 12.3 KB
description
์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐœ๋… ์ •๋ฆฌ

Sorting

์ „์ฒด ์š”์•ฝ

  1. ๋‹จ์ˆœํ•˜์ง€๋งŒ, ์กฐ๊ธˆ ๋Š๋ฆฐ ์ •๋ ฌ
    1. Bubble sort
    2. Insertion sort
    3. Selection sort
  2. ์กฐ๊ธˆ ๋ณต์žกํ•˜์ง€๋งŒ, ๋น ๋ฅธ ์ •๋ ฌ
    1. Quick sort
    2. Merge sort
    3. Heap sort
  3. ๊ธฐํƒ€
    1. Radix sort

Selection Sort

์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์ฐพ๋Š”๋‹ค.
  2. ์ฐพ์€ ๊ฐ’์„ ๋ฐฐ์—ด์˜ ๋งจ ์•ž ์š”์†Œ์™€ ๊ต์ฒดํ•œ๋‹ค.
  3. ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•œ ์š”์†Œ๋ฅผ ์ œ์™ธํ•˜๊ณ , 1๋ฒˆ 2๋ฒˆ ๊ณผ์ •์„ ๋ชจ๋‘ ๋ฐ˜๋ณตํ•œ๋‹ค.

ํŠน์ง•

  • ์ตœ์•…, ์ตœ์„ , ํ‰๊ท ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.
  • ๋ฐ์ดํ„ฐ ์š”์†Œ์— ๊ด€๊ณ„ ์—†์ด ๋ชจ๋“  ์›์†Œ์— ๋Œ€ํ•ด ๋น„๊ต ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์‹œ๊ฐ„๋ณต์žก๋„๋Š” $$O(n^2)$$
    • 1๋ฒˆ ๊ณผ์ •์—์„œ for loop๊ฐ€ n-1ํšŒ ๋ฐ˜๋ณตํ•œ๋‹ค.
    • 2๋ฒˆ ๊ณผ์ •์—์„œ ๊ฐ€์žฅ ์ž‘์€ ์ˆ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๋‚จ์€ ์›์†Œ๊ณผ ๋น„๊ตํ•œ๋‹ค : n-1, n-2...
    • 3๋ฒˆ ๊ณผ์ •์˜ ๊ตํ™˜์€ ์ƒ์ˆ˜ ์‹œ๊ฐ„์˜ ์ž‘์—…์ด๋‹ค.
    • $$T(n) = (n-1) + (n-2) + ... + 2 + 1 = \frac{n(n+1)}{2} = O(n^2)$$

์ฝ”๋“œ

func selectionSort(_ array: inout [Int]) {
    for current in 0 ..< array.count - 1 {
        var minIndex = current
        for index in current+1 ..< array.count {
            if array[index] < array[minIndex] {
                minIndex = index
            }
        }
        array.swapAt(minIndex, current)
    }
}

var array = [10, 2, 33, 20, 7]
selectionSort(&array)
print(array)

Bubble Sort

{% hint style="info" %} ์ œ์ผ ํฐ ๊ฐ’์˜ ์›์†Œ๋ฅผ ์ฐพ์•„ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•œ ํ›„ ๋‹ค์Œ ์›์†Œ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค๋Š” ์ ์—์„œ Selection Sort์™€ ๋น„์Šทํ•˜๋‹ค.

ํ•˜์ง€๋งŒ ์ตœ๋Œ“๊ฐ’์„ ์ฐพ๊ณ , ๋งˆ์ง€๋ง‰ ์œ„์น˜๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์—์„œ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•œ๋‹ค. {% endhint %}

์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ์ฒซ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ๋‹ค์Œ ์ธ๋ฑ์Šค์™€์˜ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค.
  2. ๋งŒ์•ฝ, ๋‹ค์Œ ์ธ๋ฑ์Šค์— ์ €์žฅ๋œ ๊ฐ’๋ณด๋‹ค, ํ˜„์žฌ ์ธ๋ฑ์Šค ๊ฐ’์ด ๋” ํฌ๋‹ค๋ฉด, ์ž๋ฆฌ๋ฅผ ๊ตํ™˜ํ•œ๋‹ค.
  3. ๋งˆ์ง€๋ง‰ ์›์†Œ๊นŒ์ง€ ๋น„๊ต๊ฐ€ ๋๋‚œ๋‹ค๋ฉด, ์ œ์ผ ๋งˆ์ง€๋ง‰ ์›์†Œ์—๋Š” ๋ฐฐ์—ด ์ค‘ ๊ฐ€์žฅ ํฐ ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.
  4. ํ•ด๋‹น ๊ณผ์ •์„ ๋ชจ๋“  ๋ฐฐ์—ด์ด ์ •๋ ฌ๋  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•œ๋‹ค.

ํŠน์ง•

  • ์‚ฝ์ž… ์ •๋ ฌ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ตœ์•…, ์ตœ์„ , ํ‰๊ท  ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋™์ผํ•˜๋‹ค.
  • ๋ฐ์ดํ„ฐ์˜ ์š”์†Œ์™€ ์ƒ๊ด€ ์—†์ด ๋ชจ๋“  ์›์†Œ์— ๋Œ€ํ•ด ๋น„๊ต ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์‹œ๊ฐ„๋ณต์žก๋„ = $$O(n^2)$$
    • ์ฒซ ๋ฒˆ์งธ for loop์—์„œ n-1๋ฒˆ์˜ ๋ฐ˜๋ณต์„ ํ†ตํ•ด ๊ฐ๊ฐ์˜ ์œ„์น˜๋ฅผ ์ฐพ์•„๋‚˜๊ฐ„๋‹ค.
    • ๋‘ ๋ฒˆ์งธ for loop์—์„œ index์— ๋Œ€ํ•ด ๊ฐ ์ธ์ ‘ ์š”์†Œ๋ฅผ ํƒ์ƒ‰ํ•˜๊ฒŒ ๋œ๋‹ค. (n-1, n-2, ..1)
    • ๊ตํ™˜ ์—ฐ์‚ฐ์€ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋œ๋‹ค.
    • $$T(n) = (n-1) + (n-2) + ... + 2 + 1 = \frac{n(n+1)}{2} = O(n^2)$$

์ฝ”๋“œ

func bubbleSort(_ array: inout [Int]) {
    for i in 0 ..< array.count {
        var isSwap = false
        for j in 0 ..< array.count - i - 1 {
            if array[j] > array[j+1] {
                array.swapAt(j, j+1)
                isSwap = true
            }
        }
        // ํ˜„์žฌ ๋ฐ˜๋ณต๋ฌธ์—์„œ ํ•œ ๋ฒˆ๋„ swap์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ด๋ฏธ ๋ชจ๋‘ ์ •๋ ฌ๋œ ๊ฒƒ์ด๋‹ค.
        guard isSwap else { return }
    }
}

var array = [10, 2, 33, 20, 7]
bubbleSort(&array)
print(array)

Insertion Sort

{% hint style="info" %} ๋ฐฐ์—ด์— ์›์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ์ถ”๊ฐ€ํ•˜๋ฉฐ ํ•ด๋‹น ์›์†Œ์˜ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

์ •๋ ฌ๋œ K-1 ๊ฐœ์˜ ๋ฐฐ์—ด์— ๋Œ€ํ•ด {% endhint %}

์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ์ด ๊ณผ์ •์€ i ๋ฒˆ์งธ ์›์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ธฐ ์œ„ํ•œ ๊ณผ์ •์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ž.
  1. i ๋ฒˆ์งธ ์›์†Œ๋ฅผ ์ž„์‹œ ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.
  2. i-1 ๋ฒˆ์งธ๋ถ€ํ„ฐ 1๋ฒˆ์งธ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋ฉฐ, ์ž์‹ ๋ณด๋‹ค ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ์›์†Œ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋ฉฐ ํ•ด๋‹น ์›์†Œ์˜ ์œ„์น˜๋ฅผ ์ฐพ์•„ ์ €์žฅํ•œ๋‹ค.

ํŠน์ง•

  • for loop๋Š” n-1 ๋ฒˆ ๋ฐ˜๋ณตํ•œ๋‹ค.
  • ์‚ฝ์ž…์˜ ๊ฒฝ์šฐ, ์ตœ์•…์˜ ๊ฒฝ์šฐ i-1 ๋ฒˆ ๋น„๊ตํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ตœ์•…์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” $$O(n^2)$$
    • ์—ญ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ, ๋งค๋ฒˆ i-1ํšŒ ํƒ์ƒ‰ํ•ด์•ผํ•œ๋‹ค.
  • ์ตœ์„ ์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” $$O(n)$$
    • ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ฐฐ์—ด์ด ์ •๋ ฌ๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ, 1๋ฒˆ์˜ ๋น„๊ต๋กœ ํ•ด๋‹น ์›์†Œ์˜ ์œ„์น˜๊ฐ€ ๊ฒฐ์ •๋  ์ˆ˜ ์žˆ๋‹ค.

์ฝ”๋“œ

var array = [10, 2, 33, 20, 7]
insertionSort(&array)
print(array)

func insertionSort(_ array: inout [Int]) {
    for i in 1 ..< array.count {
        for j in stride(from: i, to: 0, by: -1) {
            guard array[j] < array[j-1] else { continue }
            array.swapAt(j, j-1)
        }
    }
}

Merge Sort

๋ถ„ํ• ์ •๋ณต๋ฒ•

  • merge sort์™€ quick sort์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค. (๋ณธ์งˆ์ ์œผ๋กœ recursion์„ ์‚ฌ์šฉํ•œ๋‹ค)
  • 3๊ฐ€์ง€ ๋‹จ๊ณ„๋กœ ๊ฑฐ์ณ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ
    • ๋ถ„ํ•  : ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ž‘์€ ํฌ๊ธฐ์˜ ๋™์ผํ•œ ๋ฌธ์ œ๋“ค๋กœ ๋ถ„ํ• ํ•œ๋‹ค.
    • ์ •๋ณต : ๊ฐ๊ฐ์˜ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ์ˆœํ™˜์ ์œผ๋กœ ํ•ด๊ฒฐํ•œ๋‹ค. (๋™์ผํ•œ ๋ฌธ์ œ๋“ค๋กœ ๋ถ„ํ• ๋˜๋ฏ€๋กœ, ์ž‘์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ˆ˜ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์š”๊ตฌ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ์ตœ์ข… ๋ฌธ์ œ ํ•ด๊ฒฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ์ž‘์€ ๋ฌธ์ œ ํ•ด๊ฒฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋™์ผํ•˜๋‹ค. )
    • ํ•ฉ๋ณ‘ : ์ž‘ ๋ฌธ์ œ์˜ ํ•ด๋ฅผ ํ•ฉํ•˜์—ฌ ์›๋ž˜ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๋ฅผ ๊ตฌํ•œ๋‹ค.

์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ ๋ฐฐ์—ด์„ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค.

  2. ๊ฐ๊ฐ์„ ์ˆœํ™˜์ ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.

    ๊ธธ์ด๊ฐ€ 1์ธ ๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜๋ˆ„์–ด์งˆ ๊ฒƒ์ด๋‹ค.

  3. ์ •๋ ฌ๋œ ๋‘ ๊ฐœ์˜ ๋ฐฐ์—ด์„ ํ•ฉ์ณ ์ „์ฒด๋ฅผ ์ •๋ ฌํ•œ๋‹ค. (์ด ๋ถ€๋ถ„์˜ ๊ตฌํ˜„์ด ํ•„์š”ํ•˜๋‹ค)

    ๊ธธ์ด๊ฐ€ 1์ธ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•ฉ์น˜๋Š” ๊ณผ์ •์—์„œ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•ด์•ผํ•œ๋‹ค.

ํŠน์ง•

$$T(n) = 0, (n==1์ผ ๋•Œ)$$

$$T(n) = T(n/2) + T(n/2) + n$$

  • ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•ฉ์น  ๋•Œ ์—ฐ์‚ฐ์ด ์กด์žฌํ•œ๋‹ค.
    • ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„๋Š” ํšŸ์ˆ˜ = log(N)์ด๋‹ค. (ํŠธ๋ฆฌ์˜ ๋†’์ด ์ƒ๊ฐ)
    • ํ•ฉ์น  ๋•Œ n ๋งŒํผ์˜ ํšŸ์ˆ˜๊ฐ€ ์†Œ์š”๋œ๋‹ค.
    • ๋”ฐ๋ผ์„œ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” $$O(N) = NlogN$$

์ฝ”๋“œ

mergeSort(A[], p, r) { // A[p...r]์„ ์ •๋ ฌํ•œ๋‹ค.
    if (p < r) then {
        q <- (p+q)/2
        mergeSort(A, p, q)
        merge(A, p, q, r)
    }
}

merge(A[], p, q, r) {    
    ์ •๋ ฌ๋˜์–ด์žˆ๋Š” ๋‘ ๋ฐฐ์—ด A[p...q], A[q+1...r]์„ ํ•ฉํ•˜์—ฌ
    ์ •๋ ฌ๋œ ๋ฐฐ์—ด A[p...r]์„ ๋งŒ๋“ ๋‹ค.
}
func mergesort(_ array: [Int]) -> [Int] {
    guard array.count > 1 else { return array }
    let center = array.count / 2
    let left = Array(array[0..<center])
    let right = Array(array[center..<array.count])
    
    func merge(_ left: [Int], _ right: [Int]) -> [Int] {
        var left = left
        var right = right
        var result = [Int]()
        
        while !left.isEmpty && !right.isEmpty {
            if left[0] < right[0] {
                result.append(left.removeFirst())
            } else {
                result.append(right.removeFirst())
            }
        }
        
        return result + left + right
    }
    
    return merge(mergesort(left), mergesort(right))
}
func mergeSort(array: [Int]) -> [Int] {
    guard array.count > 1 else { return array }
    let center = array.count / 2
    let leftArray = mergeSort(array: Array(array[0..<center]))
    let rightArray = mergeSort(array: Array(array[center..<array.count]))
    return merge(left: leftArray, right: rightArray)
}

func merge(left: [Int], right: [Int]) -> [Int] {
    var leftIndex = 0
    var rightIndex = 0
    var result = [Int]()
    
    while leftIndex < left.count, rightIndex < right.count {
        if left[leftIndex] < right[rightIndex] {
            result.append(left[leftIndex])
            leftIndex += 1
        } else {
            result.append(right[rightIndex])
            rightIndex += 1
        }
    }
    if leftIndex < left.count {
        result += Array(left[leftIndex ..< left.count])
    } else {
        result += Array(right[rightIndex ..< right.count])
    }
    return result
}

Quick Sort

{% hint style="info" %} ๋ถ„ํ•  ์ •๋ณต๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. (๋ฐ์ดํ„ฐ ๋ถ„ํ•  ๋ฐฉ๋ฒ•์—์„œ Merge Sort์™€ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.)

ํŠน์ • ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋ถ„ํ• ํ•œ๋‹ค. (์ตœ์•…์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ๋™์ผํ•˜๋‹ค) {% endhint %}

ํŠน์ง•

  • Quick sort์˜ ๋ถ„ํ• ์—์„œ๋Š” ๋ฐ˜์œผ๋กœ ๋ถ„๋ฆฌ๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†๋‹ค.
    • ์ตœ์•…์˜ ๊ฒฝ์šฐ๋Š” pivot์ด ๋ฆฌ์ŠคํŠธ์—์„œ ๊ฐ€์žฅ ํฐ ๊ฐ’์ด๊ฑฐ๋‚˜, ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์ธ ๊ฒฝ์šฐ์ด๋‹ค.
  • ๋ถ„ํ•  ํ›„ Pivot ์•ž์—๋Š” pivot๋ณด๋‹ค ์ž‘๊ณ , ๋’ค๋Š” ํฌ๋‹ค.
  • ๋ถ„ํ•  ๋‹จ๊ณ„์—์„œ ์ •๋ ฌ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ฉ๋ณ‘ ๋‹จ๊ณ„์—์„œ ํŠน๋ณ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์š”๊ตฌ๋˜์ง€ ์•Š๋Š”๋‹ค.
quicksort(A[], p, r) {
    if (p < r) then 
        q = partition(A, p, r) // ๋ถ„ํ• , q๋Š” pivot์˜ ์œ„์น˜
        quicksort(A, p, q-1)   // ์™ผ์ชฝ ๋ถ€๋ถ„ ๋ฐฐ์—ด ์ •๋ ฌ
        quicksort(A, q+1, r)   // ์˜ค๋ฅธ์ชฝ ๋ถ€๋ถ„ ๋ฐฐ์—ด ์ •๋ ฌ
    }
}

partition(A[], p, r) {
    ๋ฐฐ์—ด A[p...r]์˜ ์›์†Œ๋“ค์„ A[r]์„ ๊ธฐ์ค€์œผ๋กœ ์–‘์ชฝ์œผ๋กœ ์žฌ๋ฐฐ์น˜ํ•˜๊ณ ,
    A[r]์ด ์ž๋ฆฌํ•œ ์œ„์น˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.   // ํ”ผ๋ด‡์˜ ์œ„์น˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
}
func quickSort(_ array: [Int]) -> [Int] {
    guard array.count > 1 else { return array }
    var array = array
    let pivot = array.removeLast()
    
    let left = array.filter { $0 < pivot }
    let right = array.filter { $0 >= pivot }
    
    return quickSort(left) + [pivot] + quickSort(right)
}

Heap Sort

{% hint style="info" %} ํž™ ์ •๋ ฌ์€ ์ตœ๋Œ€ ํž™์ด๋‚˜ ์ตœ์†Œ ํž™์„ ๊ตฌ์„ฑํ•˜์—ฌ ์ •๋ ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ : ์ตœ๋Œ€ํž™
  • ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ : ์ตœ์†Œ ํž™ {% endhint %}

์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ heap์œผ๋กœ ๋งŒ๋“ ๋‹ค.
  2. ํž™์—์„œ ์ตœ๋Œ“๊ฐ’๊ณผ ๋งˆ์ง€๋ง‰ ๋ฆฌํ”„๋…ธ๋“œ์™€ ์ž๋ฆฌ๋ฅผ ๋ฐ”๊พผ๋‹ค.
  3. ํž™์˜ ํฌ๊ธฐ๊ฐ€ 1 ์ค„์–ด๋“  ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. (๋งˆ์ง€๋ง‰ ๊ฐ’์€ ํž™์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹Œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. )
  4. ๋ฃจํŠธ๋…ธ๋“œ์— ๋Œ€ํ•ด์„œ Heapify(1)์„ ํ•œ๋‹ค. (remove node ํ–ˆ์„ ๋•Œ์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค)
  5. 2๋ฒˆ ~ 4๋ฒˆ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

ํŠน์ง•

  • ์ตœ์•…์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ๋ณต์žก๋„ $$O(NlogN)$$
  • sorts in place - ์ถ”๊ฐ€ ๋ฐฐ์—ด์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
  • ์ด์ง„ ํž™ ์ž๋ฃŒ๊ตฌ์กฐ(binary heap)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • Heap ์ž๋ฃŒ๊ตฌ์กฐ
      • complete binary tree์ด๋ฉด์„œ ( -> ์ธ๋ฑ์Šค๋กœ ๋ถ€๋ชจ, ์ž์‹ ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.)
      • Heap property๋ฅผ ๋งŒ์กฑํ•ด์•ผํ•œ๋‹ค. (๋ถ€๋ชจ์™€ ์ž์‹ ๊ฐ„ ๊ด€๊ณ„)
        • maxHeap : ๋ถ€๋ชจ๋Š” ์ž์‹๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๋‹ค.
        • minHeap : ๋ถ€๋ชจ๋Š” ์ž์‹๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค.
      • ํž™์€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ผ๋„, ์‚ฝ์ž… ์ˆœ์„œ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

์ฝ”๋“œ

HEAPSORT(A)                     // O(NlogN)

BUILD-MAX-HEAP(A)               // O(n)
for i <- heapSize downto 2 do   // n-1 times
    exchange A[1] <-> A[i]      // O(1)
    heapSize <- heapSize - 1    // O(1) 
    MAX-HEAPFIY(A, 1)           // O(logN)
func heapSort(_ array: [Int], _ reverse: Bool = false) -> [Int] {
    var array = array
    var result = [Int]()
    
    for i in stride(from: array.count - 1 , to: -1, by: -1) {
        if i == 0 {                           // ์›์†Œ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์„ ๋•Œ๋Š” ๋‹จ์ˆœํžˆ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
            result.append(array.removeLast())
        } else {                              // ๋‚จ์€ ์›์†Œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด, ๋‚จ์€ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํž™์„ ๋งŒ๋“ ๋‹ค.
            array = buildMaxHeap(array)
            array.swapAt(i, 0)                // ๋ฆฌํ”„๋…ธ๋“œ๋ฅผ ๋งจ ์•ž์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
            result.append(array.removeLast()) // ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•œ ํ›„ ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
        }
    }
     
     if !reverse { // ์ •๋ ฌ ๊ธฐ์ค€ ์„ ํƒ
        result.reverse()
    }
    
    return result
}

func buildMaxHeap(_ array: inout [Int]) {
    
    for i in 0 ..< array.count {                 // 1๋ฒˆ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๊นŒ์ง€ ์กฐํšŒ
        var child = i
        while child != 0 {                       // i๋ฒˆ์งธ ๋…ธ๋“œ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•œ๋‹ค.
            let parent = child / 2
            if array[parent] > array[child] { break }
            array.swapAt(parent, child)
            child = parent
        }
    }
}

์ฐธ๊ณ ํ•œ ๊ธ€ ๋ฐ ๊ฐ•์˜

[1] ๊ถŒ์˜คํ  ๊ต์ˆ˜๋‹˜์˜ ๊ธฐ๋ณธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ•์˜

[2] ๊ถŒ์˜คํ  ๊ต์ˆ˜๋‹˜์˜ ํ•ฉ๋ณ‘ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ•์˜

[3] ๊ถŒ์˜คํ  ๊ต์ˆ˜๋‹˜์˜ ๋น ๋ฅธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ•์˜

[4] ๊ฐœ๋ฐœ์ž ์†Œ๋Œ์ด๋‹˜์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํฌ์ŠคํŒ…

[5] Dev Pingu๋‹˜์˜ ํž™ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํฌ์ŠคํŒ