Swift Data Structure And Algorithm/Tree

νž™μ„ μ΄μš©ν•œ μš°μ„ μˆœμœ„ 큐(Priority Queue By Heap)

youngjaeLee1026 2022. 4. 7. 00:05

1. 문제

  • νž™μ„ μ΄μš©ν•˜μ—¬ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„

2. μž…μΆœλ ₯

  • νž™μ„ κ΅¬ν˜„ν•  λ°°μ—΄μ˜ 크기λ₯Ό μž…λ ₯ λ°›μŒ(μ™„μ „μ΄μ§„νŠΈλ¦¬ 이기 λ•Œλ¬Έμ— λ°°μ—΄λ‘œ κ΅¬ν˜„ν•  수 있음)

3. 문제 섀계

  • νž™μ˜ 경우 μ™„μ „μ΄μ§„νŠΈλ¦¬ 이기 λ•Œλ¬Έμ—, λ°°μ—΄λ‘œ κ΅¬ν˜„ν•  수 있음
  • μ™„μ „μ΄μ§„νŠΈλ¦¬λŠ” μžμ‹ λ…Έλ“œκ°€ 2개 μ΄ν•˜, μ™Όμͺ½λΆ€ν„° 값이 μ°¨λ‘€λŒ€λ‘œ μ±„μ›Œλ‚˜κ°€λŠ” 트리λ₯Ό 말함
  • μ‚½μž… μ—°μ‚°μ˜ 경우 λ°°μ—΄μ˜ κ°€μž₯ 끝에 μ›μ†Œλ₯Ό μΆ”κ°€ν•˜κ³ , μš°μ„ μˆœμœ„λ₯Ό λΉ„κ΅ν•˜μ—¬ 트리λ₯Ό μž¬κ΅¬μ„±ν•¨(λ¬Έμ œμ—μ„œλŠ” μ΅œμ†Ÿκ°’μ΄ μš°μ„ μˆœμœ„κ°€ λ†’μŒ) 트리의 λ†’μ΄λŠ” λ…Έλ“œκ°€ N개일 λ•Œ, λŒ€λž΅ log N μ΄λ―€λ‘œ, μ΅œμ•…μ˜ 경우(κ°€μž₯ μš°μ„ μˆœμœ„κ°€ 높은 값이 μ‚½μž… 됐을 경우, λ¬Έμ œμ—μ„œλŠ” μ΅œμ†Ÿκ°’) λ£¨νŠΈλ…Έλ“œ κΉŒμ§€ 비ꡐ해야 ν•˜λ―€λ‘œ O(log N)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 가짐
  • μ‚­μ œ μ—°μ‚°μ˜ 경우 μš°μ„ μˆœμœ„κ°€ κ°€μž₯ 높은 루트 λ…Έλ“œλ₯Ό μ œκ±°ν•˜κ³  κ°€μž₯ 끝 단말 λ…Έλ“œλ₯Ό λΆ€λͺ¨ λ…Έλ“œμ— μœ„μΉ˜ μ‹œν‚€κ³  μ΅œμ•…μ˜ 경우 κ°€μž₯ 단말 λ…Έλ“œ κΉŒμ§€ λ‚΄λ €κ°€μ•Ό ν•˜λ―€λ‘œ 트리의 높이인 log N 만큼 λ‚΄λ €κ°ˆ 수 있음. λ”°λΌμ„œ O(log N)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 가짐
  • 탐색 μ—°μ‚°μ˜ 경우 μš°μ„ μˆœμœ„κ°€ κ°€μž₯ 높은 루트 λ…Έλ“œλ₯Ό λ°˜ν™˜ν•˜λ©΄ λ˜λ―€λ‘œ, O(1)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 가짐
  • λ°°μ—΄λ‘œ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν–ˆμ„ λ•Œμ™€ λΉ„κ΅ν•˜κ²Œ 되면, μ‚½μž… μ—°μ‚°μ˜ 경우 O(1)κ³Ό O(log N)으둜 차이가 λ‚˜μ§€λ§Œ μ‚­μ œ μ—°μ‚°μ˜ 경우 O(N)κ³Ό O(log N)의 차이가 더 크기 λ•Œλ¬Έμ—, νž™μœΌλ‘œ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 것이 λ°”λžŒμ§ν•¨

4. 전체 μ½”λ“œ

//MARK: - μš°μ„ μˆœμœ„ 큐(νž™)

//MARK: - Framework
import Foundation

//MARK: - Type
struct PriorityQueue {
    //MARK: - Property
    var data: [Int]
    var len, capacity: Int
    
    //MARK: - Initializer
    init(_ capacity: Int) {
        self.capacity = capacity
        self.data = Array(repeating: 0, count: self.capacity + 10)
        self.len = 1
    }
    
    //MARK: - Method
    mutating func push(_ x: Int) -> Void {
        self.data[self.len] = x
        self.len += 1
        
        var currentIndex: Int = self.len - 1
        while currentIndex > 1 {
            if self.data[currentIndex] < self.data[currentIndex >> 1] {
                let temp: Int = self.data[currentIndex]
                self.data[currentIndex] = self.data[currentIndex >> 1]
                self.data[currentIndex >> 1] = temp
                
                currentIndex >>= 1
            } else {
                break
            }
        }
    }
    
    mutating func pop() -> Void {
        self.data[1] = self.data[self.len - 1]
        self.data[self.len - 1] = 0
        self.len -= 1
        
        var currentIndex: Int = 1
        while true {
            var childIndex: Int = -1
            
            if self.len - 1 < (currentIndex << 1) {
                break
            } else if (0 < (currentIndex << 1) && (currentIndex << 1) <= self.len - 1) && (currentIndex << 1 + 1) > self.len - 1 {
                childIndex = currentIndex << 1
            } else {
                childIndex = (currentIndex << 1) < (currentIndex << 1 + 1) ? (currentIndex << 1) : (currentIndex << 1 + 1)
            }
            
            if self.data[currentIndex] > self.data[childIndex] {
                let temp: Int = self.data[currentIndex]
                self.data[currentIndex] = self.data[childIndex]
                self.data[childIndex] = temp
                
                currentIndex = childIndex
            } else {
                break
            }
        }
    }
    
    func top() -> Int {
        return self.data[1]
    }
}

//MARK: - Function
func solution() -> Void {
    //MARK: - Input
    guard let n: Int = Int(readLine() ?? "0") else { return }
    var pq: PriorityQueue = PriorityQueue(n)
    
    //MARK: - Process & Output
    pq.push(5)
    pq.push(8)
    pq.push(1)
    pq.push(3)
    pq.push(3)
    
    print(pq.top()) // 1
    pq.pop()
    
    print(pq.top()) // 3
    pq.pop()
    
    print(pq.top()) // 3
    pq.pop()
    
    print(pq.top()) // 5
    pq.pop()
    
    print(pq.top()) // 8
}
solution()

 

μ „μ²΄μ½”λ“œλŠ” μ—¬κΈ°μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.