forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d1f4169
commit fc167fd
Showing
4 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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? | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |