参考来源:
栈
// 用数组实现栈-简易
class Stack {
var stack: [AnyObject]
var isEmpty: Bool {return stack.isEmpty}
var size: Int { return stack.count }
var peek: AnyObject? {return stack.last}
init() {
stack = [AnyObject]()
}
func push(object: AnyObject) {
stack.append(object)
}
func pop() -> AnyObject? {
if (!isEmpty) {
return stack.removeLast()
} else {
return nil
}
}
}
// 用数组实现栈-全面
protocol Stack {
// 持有的数据类型
associatedtype Element
// 是否为空
var isEmpty: Bool {get}
// 栈大小
var size: Int {get}
// 栈顶元素
var peek: Element? {get}
// 进栈
mutating func push(_ newElement: Element)
// 出栈
mutating func pop() -> Element?
}
struct IntegerStack: Stack {
typealias Element = Int
private var stack = [Element]()
var isEmpty: Bool { return stack.isEmpty }
var size: Int { return stack.count }
var peek: Element? { return stack.first }
mutating func push(_ newElement: Element) {
stack.append(newElement)
}
mutating func pop() -> Element? {
return stack.popLast()
}
}
队列
protocol Queue {
// 持有的数据类型
associatedtype Element
// 是否为空
var isEmpty: Bool { get }
// 队列长度
var size: Int { get }
// 队首元素
var peek: Element? { get }
// 入队
mutating func enqueue(_ newElement: Element)
// 出队
mutating func dequeue() -> Element?
}
struct IntegerQueue: Queue {
typealias Element = Int
private var left = [Element]()
private var right = [Element]()
var isEmpty: Bool { return left.isEmpty && right.isEmpty }
var size: Int { return left.count + right.count }
var peek: Element? {return left.isEmpty ? right.first : left.first }
mutating func enqueue(_ newElement: Int) {
right.append(newElement)
}
mutating func dequeue() -> Element? {
if left.isEmpty {
left = right.reversed()
right.removeAll()
}
return left.popLast()
}
}
栈和队列互相转换
// 用栈实现队列
struct MyQueue {
var stackA: Stack //上文的简易Stack
var stackB: Stack
init() {
stackA = Stack()
stackB = Stack()
}
var isEmpty: Bool {
return stackA.isEmpty && stackB.isEmpty
}
var size: Int {
get {
return stackA.size + stackB.size
}
}
fileprivate mutating func shift() {
if stackB.isEmpty {
while !stackA.isEmpty {
stackB.push(stackA.pop()!)
}
}
}
var peek: Any? {
mutating get {
shift()
return stackB.peek
}
}
mutating func enqueue(object: AnyObject) {
stackA.push(object);
}
mutating func dequeue() -> Any? {
shift()
return stackB.pop()
}
}
// 用队列实现栈
struct MyStack {
var queueA: IntegerQueue
var queueB: IntegerQueue
init() {
queueA = IntegerQueue()
queueB = IntegerQueue()
}
var isEmpty: Bool {
return queueA.isEmpty && queueB.isEmpty
}
var size: Int {
return queueA.size
}
private mutating func shift() {
while queueA.size != 1 {
queueB.enqueue(queueA.dequeue()!)
}
}
private mutating func swap() {
(queueA, queueB) = (queueB, queueA)
}
var peek: Any? {
mutating get {
shift()
let peekObj = queueA.peek
queueB.enqueue(queueA.dequeue()!)
swap()
return peekObj
}
}
mutating func push(object: Int) {
queueA.enqueue(object)
}
mutating func pop() -> Any? {
shift()
let popObj = queueA.dequeue()
swap()
return popObj
}
}
链表
// 链表
class ListNode {
var val: Int
var next: ListNode?
init(_ val: Int) {
self.val = val
self.next = nil
}
}
class List {
var head: ListNode?
var tail: ListNode?
// 尾插法
func appendToTail(_ val: Int) {
if tail == nil {
tail = ListNode(val)
head = tail
} else {
tail!.next = ListNode(val)
tail = tail!.next
}
}
// 头插法
func appendToHead(_ val: Int) {
if head == nil {
head = ListNode(val)
tail = head
} else {
let tmp = ListNode(val)
tmp.next = head
head = tmp
}
}
}
二叉树
class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init(_ val: Int) {
self.val = val
}
}
排序
归并排序
func mergeSort(_ array: [Int]) -> [Int] {
var helper = Array(repeating: 0, count: array.count), array = array
mergeSort(&array, &helper, 0, array.count - 1)
return array
}
func mergeSort(_ array: inout [Int], _ helper: inout [Int], _ low: Int, _ high: Int) {
guard low < high else {
return
}
let middle = (high - low) / 2 + low
mergeSort(&array, &helper, low, middle)
mergeSort(&array, &helper, middle+1, high)
mergeSort(&array, &helper, low, middle, high)
}
func mergeSort(_ array: inout [Int], _ helper: inout [Int], _ low: Int, _ middle: Int, _ high: Int) {
// copy both halves into a helper array
for i in low ... high {
helper[i] = array[i]
}
var heplerLeft = low, helperRight = middle + 1
var current = low
// iterate through helper array and copy the right one to original array
while heplerLeft <= middle && helperRight <= high {
if helper[heplerLeft] <= helper[helperRight] {
array[current] = helper[heplerLeft]
heplerLeft += 1
} else {
array[current] = helper[helperRight]
helperRight += 1
}
current += 1
}
// handle the rest
guard middle - heplerLeft >= 0 else {
return
}
for i in 0 ... middle - heplerLeft {
array[current + i] = helper[heplerLeft + i]
}
}
print(mergeSort([9,11,3,7,6,5]))
快速排序
func quicksort(_ array:[Int]) -> [Int] {
guard array.count > 1 else {
return array
}
let pivot = array[array.count / 2]
let left = array.filter { $0 < pivot }
let middle = array.filter { $0 == pivot }
let right = array.filter {$0 > pivot }
return quicksort(left) + middle + quicksort(right)
}
print(quicksort([1,3,5,4,2]))
搜索
二分搜索
// 假设 nums 是一个升序数组
func binarySearch(_ nums: [Int], _ target: Int) -> Bool {
var left = 0, mid = 0, right = nums.count - 1
while left <= right {
mid = (right - left) / 2 + left
if nums[mid] == target {
return true
} else if nums[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return false
}
print(binarySearch([1,2,5,6,8], 3))
深度优先搜索和广度优先搜索
DFS
// DFS 实现
func dfs(_ root: Node?) {
guard let root = root else {
return
}
visit(root)
root.visited = true
for node in root.neighbors {
if !node.visited {
dfs(node)
}
}
}
BFS
// BFS 实现
func bfs(_ root: Node?) {
var queue = [Node]()
if let root = root {
queue.append(root)
}
while !queue.isEmpty {
let current = queue.removeFirst()
visit(current)
current.visited = true
for node in current.neighbors {
if !node.visited {
queue.append(node)
}
}
}
}
动态规划
斐波拉契数列问题
// F(n) = F(n-1) + F(n-2), n >= 2
// 简单粗暴的办法。-- 爆炸💥
func Fib() -> Int {
var (prev, curr) = (0, 1)
for _ in 1 ..< 100 {
(curr, prev) = (curr + prev, curr)
}
return curr
}
// 动态规划解法
func Fib(_ n: Int) -> Int {
// 定义初始状态
guard n > 0 else {
return 0
}
if n == 1 || n == 2 {
return 1
}
// 调用动态转化方程
return Fib(n - 1) + Fib(n - 2)
}
//print(Fib(100)) // -- 电脑爆炸
// 用一个数组将计算过的值存起来,牺牲内存换效率
var nums = Array(repeating: 0, count: 100)
func Fib1(_ n: Int) -> Int {
// 定义初始状态
guard n > 0 else {
return 0
}
if n == 1 || n == 2 {
return 1
}
// 如果已经计算过,则直接调用,无需重复计算
if nums[n - 1] != 0 {
return nums[n - 1]
}
// 将计算后的值存入数组
nums[n - 1] = Fib1(n - 1) + Fib1(n - 2)
return nums[n - 1]
}
//Fib1(100)