Skip to content

Commit

Permalink
[swift] [09_queue] [add]
Browse files Browse the repository at this point in the history
  • Loading branch information
JiandanDream committed Oct 11, 2018
1 parent d1f4169 commit fc167fd
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 0 deletions.
112 changes: 112 additions & 0 deletions swift/09_queue/ArrayQueue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//
// Created by Jiandan on 2018/10/11.
// Copyright (c) 2018 Jiandan. All rights reserved.
//

import Foundation

/// 用数组实现的队列
struct ArrayQueue<T>: Queue {
typealias Element = T

/// 数组
private var items: [Element]
/// 数组最大长度
private var capacity = 0
/// 队头下标
private var head = 0
/// 队尾下标
private var tail = 0

/// 构造方法
/// - parameter defaultElement: 默认元素
/// - parameter capacity: 数组长度
init(defaultElement: Element, capacity: Int) {
self.capacity = capacity
items = [Element](repeating: defaultElement, count: capacity)
}

// MARK: Protocol: Queue

var isEmpty: Bool { return head == tail }

var size: Int { return tail - head }

var peek: Element? { return isEmpty ? nil : items[head] }

// 没有数据搬移的实现,即实现了一个有界序列
// mutating func enqueue(newElement: Element) -> Bool {
// // 整个队列都占满了
// if tail == capacity {
// return false
// }
//
// items[tail] = newElement
// tail += 1
// return true
// }
// 有数据搬移的实现,即实现了一个无界序列
mutating func enqueue(newElement: Element) -> Bool {
// 如果 tail == capacity 表示队列末尾没有空间了
if tail == capacity {
// 整个队列都占满了
if head == 0 { return false }
// 数据搬移
for i in head ..< tail {
items[i - head] = items[i]
}
// 搬移完之后重新更新 head 和 tail
tail -= head
head = 0
}

items[tail] = newElement
tail += 1
return true
}

mutating func dequeue() -> Element? {
if isEmpty {
return nil
}

let item = items[head]
head += 1
return item
}
}

/// 使用2个数组实现无界队列,用到 Swift 中 Array 较多的方法
/// 来源:《iOS 面试之道》(故胤道长,唐巧)
struct ArrayQueue2<T>: Queue {
typealias Element = T

/// 输入数组,主要负责入队
var inArray = [Element]()
/// 输出数组,主要负责出队
var outArray = [Element]()

var isEmpty: Bool { return inArray.isEmpty && outArray.isEmpty }

var size: Int { return inArray.count + outArray.count }

// 当 outArray 为空时,返回 inArray 首个元素,否则返回 outArray 末尾元素
var peek: Element? { return outArray.isEmpty ? inArray.first : outArray.last }

mutating func enqueue(newElement: Element) -> Bool {
// inArray 添加元素
inArray.append(newElement)
return true
}

mutating func dequeue() -> Element? {
if outArray.isEmpty {
// 将 inArray 倒序存入 outArray 中
outArray = inArray.reversed()
// 清空 inArray
inArray.removeAll()
}
// 弹出 outArray 最后一个元素
return outArray.popLast()
}
}
63 changes: 63 additions & 0 deletions swift/09_queue/CircularQueue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// Created by Jiandan on 2018/10/11.
// Copyright (c) 2018 Jiandan. All rights reserved.
//

import Foundation

/// 循环队列
struct CircularQueue<T>: Queue {
typealias Element = T

/// 数组
private var items: [Element]
/// 数组最大长度
private var capacity = 0
/// 队头下标
private var head = 0
/// 队尾下标
private var tail = 0

/// 构造方法
/// - parameter defaultElement: 默认元素
/// - parameter capacity: 数组长度
init(defaultElement: Element, capacity: Int) {
self.capacity = capacity
items = [Element](repeating: defaultElement, count: capacity)
}

// MARK: Protocol: Queue

var isEmpty: Bool { return head == tail }

var size: Int {
if tail >= head {
return tail - head
} else {
return (tail + 1) + (capacity - head)
}
}

var peek: Element? { return isEmpty ? nil : items[head] }

mutating func enqueue(newElement: Element) -> Bool {
// 整个队列都占满了
if (tail + 1) % capacity == head {
return false
}

items[tail] = newElement
tail = (tail + 1) % capacity
return true
}

mutating func dequeue() -> Element? {
if isEmpty {
return nil
}

let item = items[head]
head = (head + 1) % capacity
return item
}
}
21 changes: 21 additions & 0 deletions swift/09_queue/Queue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Created by Jiandan on 2018/10/11.
// Copyright (c) 2018 Jiandan. All rights reserved.
//

import Foundation

protocol Queue {
/// 持有的数据类型
associatedtype Element
/// 是否为空
var isEmpty: Bool { get }
/// 队列大小
var size: Int { get }
/// 返回队列头部元素
var peek: Element? { get }
/// 入队
mutating func enqueue(newElement: Element) -> Bool
/// 出队
mutating func dequeue() -> Element?
}
61 changes: 61 additions & 0 deletions swift/09_queue/QueueBasedOnLinkedList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Created by Jiandan on 2018/10/11.
// Copyright (c) 2018 Jiandan. All rights reserved.
//

import Foundation

class Node<T> {
var value: T?
var next: Node?

init(value: T) {
self.value = value
}
}

struct QueueBasedOnLinkedList<T>: Queue {
typealias Element = T

/// 队首
var head: Node<Element>?
/// 队尾
var tail: Node<Element>?

// MARK: Protocol: Queue

var isEmpty: Bool { return head == nil }

var size: Int {
var count = 0
while head?.next != nil {
count += 1
}
return count
}

var peek: Element? { return head?.value }

mutating func enqueue(newElement: Element) -> Bool {
if isEmpty {
// 空队列
let node = Node(value: newElement)
head = node
tail = node
} else {
tail!.next = Node(value: newElement)
tail = tail!.next
}
return true
}

mutating func dequeue() -> Element? {
if isEmpty {
return nil
}

let node = head
head = head!.next
return node?.value
}
}

0 comments on commit fc167fd

Please sign in to comment.