//
// IntQueue2.swift
// Queues
//
import Foundation
/**
IntQueue2 is our second implementation of a basic first-in, first-out queue
for Integers.
An IntQueue can be described as [n0, n1, ..., n_k], where n1 is the
least-recently-added item in the queue and is the next item to be
removed. n_k is the most-recently-added and will be the last of the
current elements to be removed.
An IntQueue can also be described constructively, with the append operation,
':', such that [n0, n1, ..., n_k] : n_k+1 is the result of enqueing n_k+1
at the end of the queue.
*/
public class IntQueue2 {
// This class represents a queue as a circular ring buffer. An array
// stores the values in the queue. Because the number of elements
// currently in the queue is usually less than the size of the
// array, we store the index of the first item in the queue and the
// total number of elements in the queue. For example, a queue with 4
// items might look like this:
//
// [__ __ n0 n1 n2 n3 __ __]
// ^frontIndex ^frontIndex+size-1
//
// As items are enqueued, front remains unchanged while size is
// incremented. As items are dequeued, front is incremented and size
// is decremented.
// TODO: write abstraction function and representation invarant
/// Starting size for the array
private let initialSize = 50
private var entries : [Int]
private var frontIndex : Int
private var size : Int
/**
**Effects**: constructs an empty queue
*/
public init() {
entries = Array<Int>(repeating: 0, count: initialSize)
frontIndex = 0
size = 0
checkRep()
}
/**
Enqueue an item
**Modifies**: self
**Effects**: places entry at the end of the queue
- Parameter entry: item to be added to the queue
*/
public func enqueue(entry: Int) {
checkRep()
// Enlarge queue if necessary
if (size == entries.count) {
var newEntries = Array<Int>(repeating: 0, count: 2 * entries.count)
for i in 0..<entries.count {
newEntries[i] = entries[(front+i)%entries.count]
}
entries = newEntries
frontIndex = 0
}
// Add item to the end of the queue, wrapping around to the front if necessary
entries[(frontIndex + size) % entries.count] = entry
size += 1
checkRep()
}
/**
Dequeue an item
**Requires**: count > 0
**Modifies**: self
**Effects**: removes the item at the front of the queue
- Returns: the item that was first in the queue
*/
public func dequeue() -> Int {
checkRep()
let ret = entries[frontIndex]
size -= 1
frontIndex = (frontIndex + 1) % entries.count
checkRep()
return ret
}
/// The item currently first in the queue
public var front : Int {
checkRep()
return entries[frontIndex]
}
/// Number of elements in the queue
public var count : Int {
checkRep()
return size
}
/// Whether count == 0
public var isEmpty : Bool
checkRep()
return entries.isEmpty
}
public func checkRep() {
// ...
}
}