[Data Structures] Queue - Array based implementation

Queue

Queue๋Š” ์•„์ฃผ ํ”ํ•œ ๊ฐœ๋…์ด๋‹ค. ํŽธ์˜์  ์•Œ๋ฐ”ํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ์ผ๋˜ ๋ง์ธ โ€˜์„ ์ž…์„ ์ถœโ€™โ€ฆ. ๋จผ์ € ๋“ค์–ด์˜จ ๊ฒŒ ๋จผ์ € ๋‚˜๊ฐ„๋‹ค๋Š” ๋œป์ด๋‹ค. ์‹ค์ œ๋กœ Queue๋Š” FIFO์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค๊ณ  ๋งํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์€ First in First out ์ด๋ž€ ๋ฌธ์žฅ์˜ ์•ฝ์ž๋‹ค. (์„ ์ž…์„ ์ถœ..!)

Common Operations

Queue๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. Array๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•
  2. Double Linked List๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•
  3. ๋ง๋ฒ„ํผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•
  4. Stack์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•

์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•œ Queue๋ฅผ ํ™•์ธํ•ด ๋ณผํ…๋ฐ ์šฐ์„ ์€ Queue์—์„œ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ํ•ญ๋ชฉ๋“ค์„ ๋จผ์ € ํ”„๋กœํ† ์ฝœ๋กœ ์ •์˜ํ•ด๋‘”๋‹ค.

protocol Queue {
    associatedtype T
    
    mutating func enqueue(_ element: T) -> Bool
    mutating func dequeue() -> T?
    
    var isEmpty: Bool { get }
    var peek: T? { get }
}

Queue ํ”„๋กœํ† ์ฝœ์„ ์ •์˜ํ•  ๋•Œ Generic Protocol์„ ์ •์˜ํ•ด์„œ ์–ด๋–ค ํƒ€์ž…์ด๋“  ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

  • enqueue: ์–ด๋–ค ๊ฐ’์„ Queue์˜ ๊ฐ€์žฅ ๋’ค์— ๋„ฃ๋Š” ๋ฉ”์„œ๋“œ
  • dequeue: Queue์˜ ๊ฐ€์žฅ ์•ž์˜ ๊ฐ’์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฉ”์„œ๋“œ
  • isEmpty: Queue๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ
  • peek: Queue์˜ ๊ฐ€์žฅ ์•ž ๋ถ€๋ถ„์˜ ์š”์†Œ๋ฅผ ํ™•์ธ

Array๋กœ Queue ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ

Array๋กœ Queue๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž. ์šฐ์„  QueueArray ๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ์•ž์— ๋งŒ๋“ค์–ด๋‘์—ˆ๋˜ Queue ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•œ๋‹ค.

struct QueueArray<T>: Queue {
    private var array: [T] = []
}

๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•  array๋ฅผ ํ•˜๋‚˜ ์„ ์–ธํ•ด๋‘์—ˆ๋‹ค. ์ด์ œ Queue๋ฅผ ์ฑ„ํƒํ–ˆ์œผ๋‹ˆ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ๋งˆ์ € ๊ตฌํ˜„ํ•œ๋‹ค.

isEmpty, peek ๊ตฌํ˜„

    var isEmpty: Bool {
        array.isEmpty
    }

    var peek: T? {
        array.first
    }
  • isEmpty๋Š” ๋ฐฐ์—ด์ด ๋น„์—ˆ๋Š”์ง€๋ฅผ, peek์€ ๋ฐฐ์—ด์˜ ๊ฐ€์žฅ ์ฒซ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

enqueue ๊ตฌํ˜„

    mutating func enqueue(_ element: T) -> Bool {
        array.append(element)
        return true
    }

๋ฐฐ์—ด๋กœ ๊ตฌํ˜„ํ•˜๋Š” Queue์—์„œ enqeue๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๋‹ค. array์˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— append๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์ด๋•Œ enqueueํ•˜๋Š” ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(1)์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฐฐ์—ด์€ ๋งจ ๋’ค์—๊ฐ€ ๋น„์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.(๋ผ๊ณ ํ•œ๋‹ค.) ํ• ๋‹น๋œ ๋งŒํผ์˜ ๋ฐฐ์—ด์ด ๊ฝ‰ ์ฐจ์žˆ๋Š” ์ƒํƒœ์—์„œ ์ƒˆ๋กœ์šด ์š”์†Œ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ทธ๋•Œ์„œ์•ผ ๋ฐฐ์—ด์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ์žฌ์กฐ์ •๋œ๋‹ค.

๋ฆฌ์‚ฌ์ด์ง•์€ O(n)์ธ ๋™์ž‘์ธ๋ฐ, ๋ฆฌ์‚ฌ์ด์ง•์„ ํ•˜๋Š” ์ž‘์—…์€ ์ƒˆ๋กœ์šด ํฌ๊ธฐ์˜ ๋ฐฐ์—ด์ด ์ƒ๊ฒจ๋‚˜๊ณ , ๊ทธ ๋ฐฐ์—ด์— ์›๋ž˜ ์žˆ๋˜ ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ์˜ฎ๊ฒจ๊ฐ€๋Š” ์ผ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ฐฐ์—ด์€ ๋ฆฌ์‚ฌ์ด์ง•์ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์•„๋งˆ ๋‘๋ฐฐ์”ฉ ํฌ๊ธฐ๊ฐ€ ๋Š˜์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์—(?) ์ž์ฃผ ์ผ์–ด๋‚˜๋Š” ์ผ์ด ์•„๋‹ˆ๊ณ  ๊ทธ๋ž˜์„œ enqueue์˜ ๋ณต์žก๋„๋ฅผ O(1)๋กœ ์ƒ๊ฐํ•œ๋‹ค.

dequeue

dequeue๋Š” ๋งจ ์•ž์—์„œ ์š”์†Œ๋ฅผ ๋นผ์˜ค๋Š” ๋™์ž‘์ด๋‹ค. ๋ฐฐ์—ด์ด ๋น„์–ด์žˆ๋‹ค๋ฉด nil์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ’์ด ์žˆ๋‹ค๋ฉด removeFirst๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐฐ์—ด์—์„œ ๊ฐ’์„ ์ œ๊ฑฐํ•œ๋‹ค.

    mutating func dequeue() -> T? {
        return isEmpty ? nil : array.removeFirst()
    }

dequeue๋Š” ํ•ญ์ƒ O(n)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋˜๋Š”๋ฐ, ์ด๊ฒƒ์€ ๋ฐฐ์—ด์˜ ๋งจ ์•ž ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฐฐ์—ด์˜ ๋งจ ์•ž ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์„ ํ•œ์นธ์”ฉ ์•ž์œผ๋กœ shiftํ•ด์ฃผ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— O(n)์œผ๋กœ ํ‘œ๊ธฐํ•œ๋‹ค.

์‹คํ–‰ ๊ฒฐ๊ณผ ๋ฐ ๋ณต์žก๋„ ์ •๋ฆฌ

  • ์‹คํ–‰ ๊ฒฐ๊ณผ

image

  • ๋ณต์žก๋„

image

Leave a comment