์ž๋ฃŒ๊ตฌ์กฐ

[Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ํž™(Heap)

๊ฒฝํ‘ธ 2023. 1. 30. 19:00
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”~

 

์˜ค๋Š˜์€ ํž™ ์ž๋ฃŒ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ํž™(Heap)์ด๋ž€?

 

๋ฐ์ดํ„ฐ์—์„œ ์ตœ๋Œ“๊ฐ’๊ณผ ์ตœ์†Ÿ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ์™„์ „์ด์ง„ํŠธ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

 

์™„์ „์ด์ง„ํŠธ๋ฆฌ

์•„๋ž˜์˜ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ

์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ฑ„์›Œ๊ฐ€๋ฉฐ ๋งˆ์ง€๋ง‰ ๋ ˆ๋ฒจ์„ ์ œ์™ธํ•˜๊ณ 

๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ํŠธ๋ฆฌ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ

 

ํž™์˜ ์ข…๋ฅ˜

 

์œ„์˜ ์„ค๋ช…์—์„œ ํž™์€

์ตœ๋Œ“๊ฐ’๊ณผ ์ตœ์†Ÿ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ธฐ ์œ„ํ•ด์„œ ๋งŒ๋“ค์–ด์ง„ ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ  ํ–ˆ๋Š”๋ฐ

 

์—ฌ๊ธฐ์„œ ์ตœ๋Œ“๊ฐ’๊ณผ ์ตœ์†Ÿ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ธฐ ์œ„ํ•ด์„œ

ํž™์€ ๋‘๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

 

์ตœ๋Œ€ ํž™

์ž์‹ ๋…ธ๋“œ์˜ ๊ฐ’์ด ์ž์‹ ์˜ ๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ํž™์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๊ฐ’์€ ํ•ญ์ƒ ์ตœ๋Œ“๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค.

 

์ตœ์†Œ ํž™

์ž์‹ ๋…ธ๋“œ์˜ ๊ฐ’์ด ์ž์‹ ์˜ ๊ฐ’๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ํž™์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๊ฐ’์€ ํ•ญ์ƒ ์ตœ์†Ÿ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค.

 

 

์œ„์˜ ๋‘๊ฐ€์ง€ ๋ชจ๋‘ BST(Binary Search Tree)์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์™ผ์ชฝ ์ž์‹, ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ ๊ฐ„์˜ ๋Œ€์†Œ๋Š” ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.

์ฆ‰, ์™ผ์ชฝ์ด๋“  ์˜ค๋ฅธ์ชฝ์ด๋“  ํฌ๊ฑฐ๋‚˜ ์ž‘์•„๋„ ์ƒ๊ด€์—†๋‹ค๋Š” ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค.

 

โœ”๏ธŽ Swift๋กœ ๊ตฌํ˜„ํ•ด ๋ณด๊ธฐ

์™ผ์ชฝ ๋…ธ๋“œ๋ถ€ํ„ฐ ๊ฐ’์„ ์ฑ„์›Œ๊ฐ€๋Š” ํŠน์ง•์œผ๋กœ ์ธํ•ด

ํž™์€ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ๋…ธ๋“œ์˜ ์ˆœ์„œ๋ฅผ index๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ธ๋ฑ์Šค 

์œ„์˜ ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•ด ๋ณด๋ฉด

 

๊ฐ’์ด 4์ธ ๋…ธ๋“œ์˜ index๋Š” 2์ž…๋‹ˆ๋‹ค.

์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๋Š” (๋ถ€๋ชจ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค * 2)์ธ 4๊ฐ€ ๋˜๊ณ  

์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ๋Š” (๋ถ€๋ชจ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค * 2 + 1)์ธ 5๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

๋ฐ˜๋Œ€๋กœ ์ž์‹๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ

๋ถ€๋ชจ๋…ธ๋“œ๋Š” (์ž์‹๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค / 2)๋กœ ( 4 / 2, 5 / 2)์ธ 2๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์ฒซ ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋ฅผ 0๋ฒˆ์ด ์•„๋‹Œ

1๋ฒˆ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ์‚ฌ์šฉํ•˜์—ฌ

์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์„ ํ•ด์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.

 

1.  Heap

class Heap<T: Comparable> {
    var heap: Array<T> = []
 
    init() { }
    init(data: T) {
        // ์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ 0๋ฒˆ ์ธ๋ฑ์Šค๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋–„๋ฌธ์— ์ฒ˜์Œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ ์ฑ„์›Œ๋‘ก๋‹ˆ๋‹ค.
        // ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
        heap.append(data)
        // 1๋ฒˆ ์ธ๋ฑ์Šค
        // ๋ฃจํŠธ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค.
        heap.append(data)
    }
}

 

2. ์‚ฝ์ž…

์‚ฝ์ž…์€ ์™„์ „์ด์ง„ํŠธ๋ฆฌ์ด๋ฏ€๋กœ

๊ฐ€์žฅ ํ•˜์œ„์˜ ์™ผ์ชฝ ๋…ธ๋“œ์— ๋จผ์ € ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์Šต๋‹ˆ๋‹ค.

 

์ดํ›„์— ์ž์‹ ์˜ ๋ถ€๋ชจ๋…ธ๋“œ์™€ ๊ฐ’์„ ๋น„๊ตํ•˜๋ฉด์„œ ์ž์‹ ์ด ๋“ค์–ด๊ฐˆ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

 

์ตœ๋Œ€ํž™์ผ ๊ฒฝ์šฐ ์ž์‹ ๋ณด๋‹ค ๋ถ€๋ชจ๊ฐ€ ๊ฐ’์ด ์ž‘๋‹ค๋ฉด ์„œ๋กœ์˜ ์œ„์น˜๋ฅผ ์Šค์œ„์นญํ•˜๊ณ 

์ตœ์†Œํž™์ผ ๊ฒฝ์šฐ ์ž์‹ ๋ณด๋‹ค ๋ถ€๋ชจ์˜ ๊ฐ’์ด ํฌ๋‹ค๋ฉด ์„œ๋กœ์˜ ์œ„์น˜๋ฅผ ์Šค์œ„์นญํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” ์ตœ๋Œ€ํž™์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

 

func insert(_ data: T) {
   if heap.count == 0 {
    	heap.append(data)
        heap.append(data)
        return
    } 
    
    heap.append(data)
    heapifyUp()
}

func heapifyUp() {

    var index = heap.count - 1 
    // ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐ๋Š” ๊ฐ€์žฅ ํ•˜์œ„๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋…ธ๋“œ. ์ฆ‰, ์ธ๋ฑ์Šค์˜ ๊ฐ€์žฅ ๋์ž…๋‹ˆ๋‹ค.
    var parent = Int(i / 2) 
    // ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ถ€๋ชจ๋…ธ๋“œ๋Š” ์ž์‹ ์˜ ์ธ๋ฑ์Šค / 2 ์ž…๋‹ˆ๋‹ค.
    
    // ์ตœ๋Œ€ํž™
    while True {
        // ์ž์‹ ๋ณด๋‹ค ๋ถ€๋ชจ๋…ธ๋“œ์˜ ๊ฐ’์ด ๋” ์ž‘๋‹ค๋ฉด ๋‘˜์˜ ์ž๋ฆฌ๋ฅผ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.
        if heap[index] > heap[parent] { 
            heap.swapAt(index, parent)
            // ์ž์‹ ์˜ ์ธ๋ฑ์Šค๊ฐ€ ๋ถ€๋ชจ์˜ ์ธ๋ฑ์Šค๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋‹ˆ ๋ถ€๋ชจ์˜ ์ธ๋ฑ์Šค๋ฅผ ์ž์‹ ์˜ ์ธ๋ฑ์Šค๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
            index = parent 
            // ๋‹ค์Œ ๋น„๊ตํ•  ๋ถ€๋ชจ์ธ๋ฑ์Šค๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
            parent = Int(i / 2) 
        } else {
            // ๋ถ€๋ชจ๋…ธ๋“œ์˜ ๊ฐ’์ด ํฌ๋‹ค๋ฉด ๋ฃจํ”„์—์„œ ํƒˆ์ถœํ•ฉ๋‹ˆ๋‹ค.
            break 
        }
    }
}

 

3. ์ถ”์ถœ

์ตœ๋Œ€ํž™์€ ์ตœ๋Œ“๊ฐ’์„ ๊บผ๋‚ด๋Š” ๊ฒƒ์„ ๋งํ•˜๊ณ  

์ตœ์†Œํž™์€ ์ตœ์†Ÿ๊ฐ’์„ ๊บผ๋‚ด๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ๋ฃจํŠธ๋…ธ๋“œ์˜ ๊ฐ’์„ ๊บผ๋‚ด๊ณ 

๊ฐ€์žฅ ํ•˜์œ„๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋ฅผ ์ตœ์ƒ์œ„ ๋…ธ๋“œ๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.

 

์ดํ›„์— ์‚ฝ์ž…๊ณผ๋Š” ๋ฐ˜๋Œ€๋กœ ์ž์‹๋…ธ๋“œ๋“ค๊ณผ ๊ฐ’์„ ๋น„๊ตํ•ด ์ž์‹ ์˜ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

 

์ตœ๋Œ€ํž™์˜ ๊ฒฝ์šฐ, ์ž์‹ ๋ณด๋‹ค ์ž์‹๋…ธ๋“œ์˜ ๊ฐ’์ด ํฌ๋‹ค๋ฉด ๊ณ„์†ํ•ด์„œ ์Šค์œ„์นญํ•˜๋ฉด์„œ ๋‚ด๋ ค๊ฐ‘๋‹ˆ๋‹ค.

์ตœ์†Œํž™์˜ ๊ฒฝ์šฐ, ์ž์‹ ๋ณด๋‹ค ์ž์‹๋…ธ๋“œ์˜ ๊ฐ’์ด ์ž‘๋‹ค๋ฉด ๊ณ„์†ํ•ด์„œ ์Šค์œ„์นญํ•˜๋ฉด์„œ ๋‚ด๋ ค๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

func pop<T : data>() -> T {
    // popํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ
    var popItem = heap[1]
    // ๋ฃจํŠธ๋…ธ๋“œ์˜ ๊ฐ’์„ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋กœ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.
    heap[1] = heap[heap.count - 1] 
    
    heap.popLast()
    heapifyDown(index: 1)
    
    return popItem
}

func heapifyDown(index: Int) {

    var left = index * 2
    var right = index * 2 + 1
    var max = index
    
    // ์™ผ์ชฝ ๋…ธ๋“œ์˜ ๊ฐ’์ด ์ž์‹ ๋ณด๋‹ค ํฌ๋‹ค๋ฉด ํ•ด๋‹น ์ธ๋ฑ์Šค๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
    if left <= heap.count - 1 && heap[left] > heap[max] { 
    	max = left
    }
	// ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ์˜ ๊ฐ’์ด ์ž์‹ ๋ณด๋‹ค ํฌ๋‹ค๋ฉด ํ•ด๋‹น ์ธ๋ฑ์Šค๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
    if right <= heap.count - 1 && heap[right] > heap[max] {
    	max = right
    }
	
    // ๊ธฐ์กด์˜ ์ž์‹ ์˜ ์ธ๋ฑ์Šค์™€ ๋‹ค๋ฅธ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ๋‹ค๋ฉด
    if max != index {
        heap.swapAt(index, max)
        heapifyDown(index: max) 
        // ๋ณ€๊ฒฝ๋œ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ๋‹ค์‹œ heapify
    }
}

 

๋” ์ข‹์€ ๊ธ€๋กœ ์ฐพ์•„๋ต™๊ฒ ์Šต๋‹ˆ๋‹ค ~

 

๊ทธ๋Ÿผ ์•ˆ๋…• ~ ๐Ÿ‘‹๐Ÿป๐Ÿ‘‹๐Ÿป๐Ÿ‘‹๐Ÿป

๋ฐ˜์‘ํ˜•