Swift 算法与数据结构:从理论到实际 iOS 项目
\nSwift 不仅仅是 Apple 生态系统中一种现代且安全的编程语言。它是一个强大的工具,能够让你为 iOS、macOS、watchOS 和 tvOS 编写高效且高性能的代码。然而,要创建真正快速且可扩展的应用程序,仅仅了解语法是不够的。理解基础算法和数据结构,正是初级开发人员与高级工程师之间的区别所在。
\n在本文中,我们将通过实际示例,用 Swift 语言解析关键的数据结构和算法。你将看到如何实现栈、队列、二分查找和排序,并了解这些知识在真实 iOS 应用开发中的应用场景。让我们开始吧!
\n\n1. 栈 (Stack) 和队列 (Queue):基础结构
\n栈和队列是两种基础数据结构,在 iOS 开发中经常使用。例如,栈用于 UINavigationController 中的导航,而队列用于管理 OperationQueue 或 DispatchQueue 中的任务。
栈的实现 (LIFO — 后进先出)
\n栈的工作原理是“后进先出”。元素的添加 (push) 和删除 (pop) 都在同一端——栈顶进行。
\nstruct Stack<Element> {\n private var storage: [Element] = []\n \n mutating func push(_ element: Element) {\n storage.append(element)\n }\n \n @discardableResult\n mutating func pop() -> Element? {\n return storage.popLast()\n }\n \n func peek() -> Element? {\n return storage.last\n }\n \n var isEmpty: Bool {\n return storage.isEmpty\n }\n}\n\n// 使用示例\nvar navigationStack = Stack<String>()\nnavigationStack.push("主屏幕")\nnavigationStack.push("商品详情")\nnavigationStack.push("购物车")\nprint(navigationStack.pop() ?? "") // 输出:"购物车"\nprint(navigationStack.peek() ?? "") // 输出:"商品详情"\n应用场景: 撤销/重做操作 (Undo/Redo)、解析器中括号匹配检查、深度优先遍历 (DFS)。
\n\n队列的实现 (FIFO — 先进先出)
\n队列的工作原理是“先进先出”。元素在尾部添加 (enqueue),从头部移除 (dequeue)。
\nstruct Queue<Element> {\n private var storage: [Element] = []\n \n mutating func enqueue(_ element: Element) {\n storage.append(element)\n }\n \n @discardableResult\n mutating func dequeue() -> Element? {\n guard !storage.isEmpty else { return nil }\n return storage.removeFirst()\n }\n \n func peek() -> Element? {\n return storage.first\n }\n \n var isEmpty: Bool {\n return storage.isEmpty\n }\n}\n\n// 使用示例\nvar taskQueue = Queue<String>()\ntaskQueue.enqueue("加载图片")\ntaskQueue.enqueue("同步数据")\ntaskQueue.enqueue("发送分析报告")\nprint(taskQueue.dequeue() ?? "") // 输出:"加载图片"\n应用场景: 网络请求处理、广度优先遍历 (BFS)、后台线程中的任务队列。
\n\n2. 二分查找:速度与简洁的权衡
\n二分查找是一种经典算法,能在已排序数组中用对数时间 O(log n) 找到目标元素。在 iOS 中,它常用于处理大型排序数据集,例如搜索联系人或数据库记录。
\nfunc binarySearch<T: Comparable>(in array: [T], target: T) -> Int? {\n var lowerBound = 0\n var upperBound = array.count - 1\n \n while lowerBound <= upperBound {\n let midIndex = (lowerBound + upperBound) / 2\n let midValue = array[mid