Add build script for Swift.

pull/351/head^2
krahets 2 years ago
parent 05f0054005
commit 38751cc5f5

@ -12,8 +12,8 @@ func swap(nums: inout [Int], i: Int, j: Int) {
}
/* */
// -
func quickSortPartition(nums: inout [Int], left: Int, right: Int) -> Int {
/* */
func partition(nums: inout [Int], left: Int, right: Int) -> Int {
// nums[left]
var i = left
var j = right
@ -30,22 +30,23 @@ func quickSortPartition(nums: inout [Int], left: Int, right: Int) -> Int {
return i //
}
// -
/* */
func quickSort(nums: inout [Int], left: Int, right: Int) {
// 1
if left >= right {
return
}
//
let pivot = quickSortPartition(nums: &nums, left: left, right: right)
let pivot = partition(nums: &nums, left: left, right: right)
//
quickSort(nums: &nums, left: left, right: pivot - 1)
quickSort(nums: &nums, left: pivot + 1, right: right)
}
/* */
// -
func quickSortMedianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
/* */
func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
if (nums[left] < nums[mid]) != (nums[left] < nums[right]) {
return left
} else if (nums[mid] < nums[left]) != (nums[mid] < nums[right]) {
@ -55,42 +56,37 @@ func quickSortMedianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
}
}
// -
func quickSortMedianPartition(nums: inout [Int], left: Int, right: Int) -> Int {
/* */
func partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {
//
let med = quickSortMedianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)
let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)
//
swap(nums: &nums, i: left, j: med)
return quickSortPartition(nums: &nums, left: left, right: right)
return partition(nums: &nums, left: left, right: right)
}
// -
/* */
func quickSortMedian(nums: inout [Int], left: Int, right: Int) {
// 1
if left >= right {
return
}
//
let pivot = quickSortMedianPartition(nums: &nums, left: left, right: right)
let pivot = partitionMedian(nums: &nums, left: left, right: right)
//
quickSortMedian(nums: &nums, left: left, right: pivot - 1)
quickSortMedian(nums: &nums, left: pivot + 1, right: right)
}
/* */
// -
func quickSortTailCallPartition(nums: inout [Int], left: Int, right: Int) -> Int {
quickSortPartition(nums: &nums, left: left, right: right)
}
// -
/* */
func quickSortTailCall(nums: inout [Int], left: Int, right: Int) {
var left = left
var right = right
// 1
while left < right {
//
let pivot = quickSortTailCallPartition(nums: &nums, left: left, right: right)
let pivot = partition(nums: &nums, left: left, right: right)
//
if (pivot - left) < (right - pivot) {
quickSortTailCall(nums: &nums, left: left, right: pivot - 1) //

@ -181,14 +181,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
=== "Swift"
```swift title="array.swift"
/* 随机返回一个数组元素 */
func randomAccess(nums: [Int]) -> Int {
// 在区间 [0, nums.count) 中随机抽取一个数字
let randomIndex = nums.indices.randomElement()!
// 获取并返回随机元素
let randomNum = nums[randomIndex]
return randomNum
}
[class]{}-[func]{randomAccess}
```
=== "Zig"
@ -281,17 +274,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
=== "Swift"
```swift title="array.swift"
/* 扩展数组长度 */
func extend(nums: [Int], enlarge: Int) -> [Int] {
// 初始化一个扩展长度后的数组
var res = Array(repeating: 0, count: nums.count + enlarge)
// 将原数组中的所有元素复制到新数组
for i in nums.indices {
res[i] = nums[i]
}
// 返回扩展后的新数组
return res
}
[class]{}-[func]{extend}
```
=== "Zig"
@ -415,24 +398,9 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
=== "Swift"
```swift title="array.swift"
/* 在数组的索引 index 处插入元素 num */
func insert(nums: inout [Int], num: Int, index: Int) {
// 把索引 index 以及之后的所有元素向后移动一位
for i in sequence(first: nums.count - 1, next: { $0 > index + 1 ? $0 - 1 : nil }) {
nums[i] = nums[i - 1]
}
// 将 num 赋给 index 处元素
nums[index] = num
}
[class]{}-[func]{insert}
/* 删除索引 index 处元素 */
func remove(nums: inout [Int], index: Int) {
let count = nums.count
// 把索引 index 之后的所有元素向前移动一位
for i in sequence(first: index, next: { $0 < count - 1 - 1 ? $0 + 1 : nil }) {
nums[i] = nums[i + 1]
}
}
[class]{}-[func]{remove}
```
=== "Zig"
@ -539,18 +507,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
=== "Swift"
```swift title="array.swift"
/* 遍历数组 */
func traverse(nums: [Int]) {
var count = 0
// 通过索引遍历数组
for _ in nums.indices {
count += 1
}
// 直接遍历数组
for _ in nums {
count += 1
}
}
[class]{}-[func]{traverse}
```
=== "Zig"
@ -644,15 +601,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
=== "Swift"
```swift title="array.swift"
/* 在数组中查找指定元素 */
func find(nums: [Int], target: Int) -> Int {
for i in nums.indices {
if nums[i] == target {
return i
}
}
return -1
}
[class]{}-[func]{find}
```
=== "Zig"

@ -572,17 +572,7 @@ comments: true
=== "Swift"
```swift title="linked_list.swift"
/* 访问链表中索引为 index 的结点 */
func access(head: ListNode, index: Int) -> ListNode? {
var head: ListNode? = head
for _ in 0 ..< index {
if head == nil {
return nil
}
head = head?.next
}
return head
}
[class]{}-[func]{access}
```
=== "Zig"
@ -680,19 +670,7 @@ comments: true
=== "Swift"
```swift title="linked_list.swift"
/* 在链表中查找值为 target 的首个结点 */
func find(head: ListNode, target: Int) -> Int {
var head: ListNode? = head
var index = 0
while head != nil {
if head?.val == target {
return index
}
head = head?.next
index += 1
}
return -1
}
[class]{}-[func]{find}
```
=== "Zig"

@ -956,99 +956,7 @@ comments: true
=== "Swift"
```swift title="my_list.swift"
/* 列表类简易实现 */
class MyList {
private var nums: [Int] // 数组(存储列表元素)
private var _capacity = 10 // 列表容量
private var _size = 0 // 列表长度(即当前元素数量)
private let extendRatio = 2 // 每次列表扩容的倍数
/* 构造函数 */
init() {
nums = Array(repeating: 0, count: _capacity)
}
/* 获取列表长度(即当前元素数量)*/
func size() -> Int {
_size
}
/* 获取列表容量 */
func capacity() -> Int {
_capacity
}
/* 访问元素 */
func get(index: Int) -> Int {
// 索引如果越界则抛出错误,下同
if index < 0 || index >= _size {
fatalError("索引越界")
}
return nums[index]
}
/* 更新元素 */
func set(index: Int, num: Int) {
if index < 0 || index >= _size {
fatalError("索引越界")
}
nums[index] = num
}
/* 尾部添加元素 */
func add(num: Int) {
// 元素数量超出容量时,触发扩容机制
if _size == _capacity {
extendCapacity()
}
nums[_size] = num
// 更新元素数量
_size += 1
}
/* 中间插入元素 */
func insert(index: Int, num: Int) {
if index < 0 || index >= _size {
fatalError("索引越界")
}
// 元素数量超出容量时,触发扩容机制
if _size == _capacity {
extendCapacity()
}
// 将索引 index 以及之后的元素都向后移动一位
for j in sequence(first: _size - 1, next: { $0 >= index + 1 ? $0 - 1 : nil }) {
nums[j + 1] = nums[j]
}
nums[index] = num
// 更新元素数量
_size += 1
}
/* 删除元素 */
@discardableResult
func remove(index: Int) -> Int {
if index < 0 || index >= _size {
fatalError("索引越界")
}
let num = nums[index]
// 将索引 index 之后的元素都向前移动一位
for j in index ..< (_size - 1) {
nums[j] = nums[j + 1]
}
// 更新元素数量
_size -= 1
// 返回被删除元素
return num
}
/* 列表扩容 */
func extendCapacity() {
// 新建一个长度为 size 的数组,并将原数组拷贝到新数组
nums = nums + Array(repeating: 0, count: _capacity * (extendRatio - 1))
// 更新列表容量
_capacity = nums.count
}
}
[class]{MyList}-[func]{}
```
=== "Zig"

@ -665,22 +665,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 常数阶 */
func constant(n: Int) {
// 常量、变量、对象占用 O(1) 空间
let a = 0
var b = 0
let nums = Array(repeating: 0, count: 10000)
let node = ListNode(x: 0)
// 循环中的变量占用 O(1) 空间
for _ in 0 ..< n {
let c = 0
}
// 循环中的函数占用 O(1) 空间
for _ in 0 ..< n {
function()
}
}
[class]{}-[func]{constant}
```
=== "Zig"
@ -797,15 +782,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 线性阶 */
func linear(n: Int) {
// 长度为 n 的数组占用 O(n) 空间
let nums = Array(repeating: 0, count: n)
// 长度为 n 的列表占用 O(n) 空间
let nodes = (0 ..< n).map { ListNode(x: $0) }
// 长度为 n 的哈希表占用 O(n) 空间
let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, "\($0)") })
}
[class]{}-[func]{linear}
```
=== "Zig"
@ -901,14 +878,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 线性阶(递归实现) */
func linearRecur(n: Int) {
print("递归 n = \(n)")
if n == 1 {
return
}
linearRecur(n: n - 1)
}
[class]{}-[func]{linearRecur}
```
=== "Zig"
@ -1004,11 +974,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 平方阶 */
func quadratic(n: Int) {
// 二维列表占用 O(n^2) 空间
let numList = Array(repeating: Array(repeating: 0, count: n), count: n)
}
[class]{}-[func]{quadratic}
```
=== "Zig"
@ -1100,15 +1066,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 平方阶(递归实现) */
func quadraticRecur(n: Int) -> Int {
if n <= 0 {
return 0
}
// 数组 nums 长度为 n, n-1, ..., 2, 1
let nums = Array(repeating: 0, count: n)
return quadraticRecur(n: n - 1)
}
[class]{}-[func]{quadraticRecur}
```
=== "Zig"
@ -1199,16 +1157,7 @@ $$
=== "Swift"
```swift title="space_complexity.swift"
/* 指数阶(建立满二叉树) */
func buildTree(n: Int) -> TreeNode? {
if n == 0 {
return nil
}
let root = TreeNode(x: 0)
root.left = buildTree(n: n - 1)
root.right = buildTree(n: n - 1)
return root
}
[class]{}-[func]{buildTree}
```
=== "Zig"

@ -108,17 +108,7 @@ comments: true
=== "Swift"
```swift title="leetcode_two_sum.swift"
func twoSumBruteForce(nums: [Int], target: Int) -> [Int] {
// 两层循环,时间复杂度 O(n^2)
for i in nums.indices.dropLast() {
for j in nums.indices.dropFirst(i + 1) {
if nums[i] + nums[j] == target {
return [i, j]
}
}
}
return [0]
}
[class]{}-[func]{twoSumBruteForce}
```
=== "Zig"
@ -229,18 +219,7 @@ comments: true
=== "Swift"
```swift title="leetcode_two_sum.swift"
func twoSumHashTable(nums: [Int], target: Int) -> [Int] {
// 辅助哈希表,空间复杂度 O(n)
var dic: [Int: Int] = [:]
// 单层循环,时间复杂度 O(n)
for i in nums.indices {
if let j = dic[target - nums[i]] {
return [j, i]
}
dic[nums[i]] = i
}
return [0]
}
[class]{}-[func]{twoSumHashTable}
```
=== "Zig"

@ -868,15 +868,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 常数阶 */
func constant(n: Int) -> Int {
var count = 0
let size = 100000
for _ in 0 ..< size {
count += 1
}
return count
}
[class]{}-[func]{constant}
```
=== "Zig"
@ -971,14 +963,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 线性阶 */
func linear(n: Int) -> Int {
var count = 0
for _ in 0 ..< n {
count += 1
}
return count
}
[class]{}-[func]{linear}
```
=== "Zig"
@ -1078,15 +1063,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 线性阶(遍历数组) */
func arrayTraversal(nums: [Int]) -> Int {
var count = 0
// 循环次数与数组长度成正比
for _ in nums {
count += 1
}
return count
}
[class]{}-[func]{arrayTraversal}
```
=== "Zig"
@ -1191,17 +1168,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 平方阶 */
func quadratic(n: Int) -> Int {
var count = 0
// 循环次数与数组长度成平方关系
for _ in 0 ..< n {
for _ in 0 ..< n {
count += 1
}
}
return count
}
[class]{}-[func]{quadratic}
```
=== "Zig"
@ -1341,24 +1308,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 平方阶(冒泡排序) */
func bubbleSort(nums: inout [Int]) -> Int {
var count = 0 // 计数器
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
for i in sequence(first: nums.count - 1, next: { $0 > 0 + 1 ? $0 - 1 : nil }) {
// 内循环:冒泡操作
for j in 0 ..< i {
if nums[j] > nums[j + 1] {
// 交换 nums[j] 与 nums[j + 1]
let tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 // 元素交换包含 3 个单元操作
}
}
}
return count
}
[class]{}-[func]{bubbleSort}
```
=== "Zig"
@ -1485,20 +1435,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 指数阶(循环实现) */
func exponential(n: Int) -> Int {
var count = 0
var base = 1
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for _ in 0 ..< n {
for _ in 0 ..< base {
count += 1
}
base *= 2
}
// count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
return count
}
[class]{}-[func]{exponential}
```
=== "Zig"
@ -1594,13 +1531,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 指数阶(递归实现) */
func expRecur(n: Int) -> Int {
if n == 1 {
return 1
}
return expRecur(n: n - 1) + expRecur(n: n - 1) + 1
}
[class]{}-[func]{expRecur}
```
=== "Zig"
@ -1698,16 +1629,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 对数阶(循环实现) */
func logarithmic(n: Int) -> Int {
var count = 0
var n = n
while n > 1 {
n = n / 2
count += 1
}
return count
}
[class]{}-[func]{logarithmic}
```
=== "Zig"
@ -1799,13 +1721,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 对数阶(递归实现) */
func logRecur(n: Int) -> Int {
if n <= 1 {
return 0
}
return logRecur(n: n / 2) + 1
}
[class]{}-[func]{logRecur}
```
=== "Zig"
@ -1907,17 +1823,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 线性对数阶 */
func linearLogRecur(n: Double) -> Int {
if n <= 1 {
return 1
}
var count = linearLogRecur(n: n / 2) + linearLogRecur(n: n / 2)
for _ in 0 ..< Int(n) {
count += 1
}
return count
}
[class]{}-[func]{linearLogRecur}
```
=== "Zig"
@ -2032,18 +1938,7 @@ $$
=== "Swift"
```swift title="time_complexity.swift"
/* 阶乘阶(递归实现) */
func factorialRecur(n: Int) -> Int {
if n == 0 {
return 1
}
var count = 0
// 从 1 个分裂出 n 个
for _ in 0 ..< n {
count += factorialRecur(n: n - 1)
}
return count
}
[class]{}-[func]{factorialRecur}
```
=== "Zig"

@ -572,55 +572,9 @@ $$
=== "Swift"
```swift title="array_hash_map.swift"
/* 键值对 int->String */
class Entry {
var key: Int
var val: String
init(key: Int, val: String) {
self.key = key
self.val = val
}
}
/* 基于数组简易实现的哈希表 */
class ArrayHashMap {
private var bucket: [Entry?] = []
init() {
// 初始化一个长度为 100 的桶(数组)
for _ in 0 ..< 100 {
bucket.append(nil)
}
}
/* 哈希函数 */
private func hashFunc(key: Int) -> Int {
let index = key % 100
return index
}
/* 查询操作 */
func get(key: Int) -> String? {
let index = hashFunc(key: key)
let pair = bucket[index]
return pair?.val
}
/* 添加操作 */
func put(key: Int, val: String) {
let pair = Entry(key: key, val: val)
let index = hashFunc(key: key)
bucket[index] = pair
}
[class]{Entry}-[func]{}
/* 删除操作 */
func remove(key: Int) {
let index = hashFunc(key: key)
// 置为 nil ,代表删除
bucket[index] = nil
}
}
[class]{ArrayHashMap}-[func]{}
```
=== "Zig"

@ -350,27 +350,11 @@ comments: true
=== "Swift"
```swift title="my_heap.swift"
var maxHeap: [Int]
/* 构造函数,建立空堆 */
init() {
maxHeap = []
}
/* 获取左子结点索引 */
func left(i: Int) -> Int {
2 * i + 1
}
[class]{MaxHeap}-[func]{left}
/* 获取右子结点索引 */
func right(i: Int) -> Int {
2 * i + 2
}
[class]{MaxHeap}-[func]{right}
/* 获取父结点索引 */
func parent(i: Int) -> Int {
(i - 1) / 2 // 向下整除
}
[class]{MaxHeap}-[func]{parent}
```
=== "Zig"
@ -437,10 +421,7 @@ comments: true
=== "Swift"
```swift title="my_heap.swift"
/* 访问堆顶元素 */
func peek() -> Int {
maxHeap[0]
}
[class]{MaxHeap}-[func]{peek}
```
=== "Zig"
@ -556,30 +537,9 @@ comments: true
=== "Swift"
```swift title="my_heap.swift"
/* 元素入堆 */
func push(val: Int) {
// 添加结点
maxHeap.append(val)
// 从底至顶堆化
siftUp(i: size() - 1)
}
[class]{MaxHeap}-[func]{push}
/* 从结点 i 开始,从底至顶堆化 */
func siftUp(i: Int) {
var i = i
while true {
// 获取结点 i 的父结点
let p = parent(i: i)
// 当“越过根结点”或“结点无需修复”时,结束堆化
if p < 0 || maxHeap[i] <= maxHeap[p] {
break
}
// 交换两结点
swap(i: i, j: p)
// 循环向上堆化
i = p
}
}
[class]{MaxHeap}-[func]{siftUp}
```
=== "Zig"
@ -728,46 +688,9 @@ comments: true
=== "Swift"
```swift title="my_heap.swift"
/* 元素出堆 */
func poll() -> Int {
// 判空处理
if isEmpty() {
fatalError("堆为空")
}
// 交换根结点与最右叶结点(即交换首元素与尾元素)
swap(i: 0, j: size() - 1)
// 删除结点
let val = maxHeap.remove(at: size() - 1)
// 从顶至底堆化
siftDown(i: 0)
// 返回堆顶元素
return val
}
[class]{MaxHeap}-[func]{poll}
/* 从结点 i 开始,从顶至底堆化 */
func siftDown(i: Int) {
var i = i
while true {
// 判断结点 i, l, r 中值最大的结点,记为 ma
let l = left(i: i)
let r = right(i: i)
var ma = i
if l < size(), maxHeap[l] > maxHeap[ma] {
ma = l
}
if r < size(), maxHeap[r] > maxHeap[ma] {
ma = r
}
// 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
if ma == i {
break
}
// 交换两结点
swap(i: i, j: ma)
// 循环向下堆化
i = ma
}
}
[class]{MaxHeap}-[func]{siftDown}
```
=== "Zig"
@ -842,15 +765,7 @@ comments: true
=== "Swift"
```swift title="my_heap.swift"
/* 构造函数,根据输入列表建堆 */
init(nums: [Int]) {
// 将列表元素原封不动添加进堆
maxHeap = nums
// 堆化除叶结点以外的其他所有结点
for i in stride(from: parent(i: size() - 1), through: 0, by: -1) {
siftDown(i: i)
}
}
[class]{MaxHeap}-[func]{init}
```
=== "Zig"

@ -137,25 +137,7 @@ $$
=== "Swift"
```swift title="binary_search.swift"
/* 二分查找(双闭区间) */
func binarySearch(nums: [Int], target: Int) -> Int {
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
var i = 0
var j = nums.count - 1
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
while i <= j {
let m = (i + j) / 2 // 计算中点索引 m
if nums[m] < target { // target [m+1, j]
i = m + 1
} else if nums[m] > target { // 此情况说明 target 在区间 [i, m-1] 中
j = m - 1
} else { // 找到目标元素,返回其索引
return m
}
}
// 未找到目标元素,返回 -1
return -1
}
[class]{}-[func]{binarySearch}
```
=== "Zig"
@ -254,25 +236,7 @@ $$
=== "Swift"
```swift title="binary_search.swift"
/* 二分查找(左闭右开) */
func binarySearch1(nums: [Int], target: Int) -> Int {
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
var i = 0
var j = nums.count
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
while i < j {
let m = (i + j) / 2 // 计算中点索引 m
if nums[m] < target { // target [m+1, j)
i = m + 1
} else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中
j = m
} else { // 找到目标元素,返回其索引
return m
}
}
// 未找到目标元素,返回 -1
return -1
}
[class]{}-[func]{binarySearch1}
```
=== "Zig"

@ -82,12 +82,7 @@ comments: true
=== "Swift"
```swift title="hashing_search.swift"
/* 哈希查找(数组) */
func hashingSearchArray(map: [Int: Int], target: Int) -> Int {
// 哈希表的 key: 目标元素value: 索引
// 若哈希表中无此 key ,返回 -1
return map[target, default: -1]
}
[class]{}-[func]{hashingSearchArray}
```
=== "Zig"
@ -167,12 +162,7 @@ comments: true
=== "Swift"
```swift title="hashing_search.swift"
/* 哈希查找(链表) */
func hashingSearchLinkedList(map: [Int: ListNode], target: Int) -> ListNode? {
// 哈希表的 key: 目标结点值value: 结点对象
// 若哈希表中无此 key ,返回 null
return map[target]
}
[class]{}-[func]{hashingSearchLinkedList}
```
=== "Zig"

@ -87,18 +87,7 @@ comments: true
=== "Swift"
```swift title="linear_search.swift"
/* 线性查找(数组) */
func linearSearchArray(nums: [Int], target: Int) -> Int {
// 遍历数组
for i in nums.indices {
// 找到目标元素,返回其索引
if nums[i] == target {
return i
}
}
// 未找到目标元素,返回 -1
return -1
}
[class]{}-[func]{linearSearchArray}
```
=== "Zig"
@ -185,20 +174,7 @@ comments: true
=== "Swift"
```swift title="linear_search.swift"
/* 线性查找(链表) */
func linearSearchLinkedList(head: ListNode?, target: Int) -> ListNode? {
var head = head
// 遍历链表
while head != nil {
// 找到目标结点,返回之
if head?.val == target {
return head
}
head = head?.next
}
// 未找到目标结点,返回 null
return nil
}
[class]{}-[func]{linearSearchLinkedList}
```
=== "Zig"

@ -144,21 +144,7 @@ comments: true
=== "Swift"
```swift title="bubble_sort.swift"
/* 冒泡排序 */
func bubbleSort(nums: inout [Int]) {
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
for i in stride(from: nums.count - 1, to: 0, by: -1) {
// 内循环:冒泡操作
for j in stride(from: 0, to: i, by: 1) {
if nums[j] > nums[j + 1] {
// 交换 nums[j] 与 nums[j + 1]
let tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
}
}
}
}
[class]{}-[func]{bubbleSort}
```
=== "Zig"
@ -293,25 +279,7 @@ comments: true
=== "Swift"
```swift title="bubble_sort.swift"
/* 冒泡排序(标志优化)*/
func bubbleSortWithFlag(nums: inout [Int]) {
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
for i in stride(from: nums.count - 1, to: 0, by: -1) {
var flag = false // 初始化标志位
for j in stride(from: 0, to: i, by: 1) {
if nums[j] > nums[j + 1] {
// 交换 nums[j] 与 nums[j + 1]
let tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
flag = true // 记录交换元素
}
}
if !flag { // 此轮冒泡未交换任何元素,直接跳出
break
}
}
}
[class]{}-[func]{bubbleSortWithFlag}
```
=== "Zig"

@ -119,20 +119,7 @@ comments: true
=== "Swift"
```swift title="insertion_sort.swift"
/* 插入排序 */
func insertionSort(nums: inout [Int]) {
// 外循环base = nums[1], nums[2], ..., nums[n-1]
for i in stride(from: 1, to: nums.count, by: 1) {
let base = nums[i]
var j = i - 1
// 内循环:将 base 插入到左边的正确位置
while j >= 0, nums[j] > base {
nums[j + 1] = nums[j] // 1. 将 nums[j] 向右移动一位
j -= 1
}
nums[j + 1] = base // 2. 将 base 赋值到正确位置
}
}
[class]{}-[func]{insertionSort}
```
=== "Zig"

@ -54,27 +54,9 @@ comments: true
=== "C++"
```cpp title="quick_sort.cpp"
/* 元素交换 */
void swap(vector<int>& nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
[class]{QuickSort}-[func]{swap}
/* 哨兵划分 */
int partition(vector<int>& nums, int left, int right) {
// 以 nums[left] 作为基准数
int i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left])
j--; // 从右向左找首个小于基准数的元素
while (i < j && nums[i] <= nums[left])
i++; // 从左向右找首个大于基准数的元素
swap(nums, i, j); // 交换这两个元素
}
swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引
}
[class]{QuickSort}-[func]{partition}
```
=== "Python"
@ -109,59 +91,17 @@ comments: true
=== "JavaScript"
```javascript title="quick_sort.js"
/* 元素交换 */
function swap(nums, i, j) {
let tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
[class]{QuickSort}-[func]{swap}
/* 哨兵划分 */
function partition(nums, left, right) {
// 以 nums[left] 作为基准数
let i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j -= 1; // 从右向左找首个小于基准数的元素
}
while (i < j && nums[i] <= nums[left]) {
i += 1; // 从左向右找首个大于基准数的元素
}
// 元素交换
swap(nums, i, j); // 交换这两个元素
}
swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引
}
[class]{QuickSort}-[func]{partition}
```
=== "TypeScript"
```typescript title="quick_sort.ts"
/* 元素交换 */
function swap(nums: number[], i: number, j: number): void {
let tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
[class]{QuickSort}-[func]{swap}
/* 哨兵划分 */
function partition(nums: number[], left: number, right: number): number {
// 以 nums[left] 作为基准数
let i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j -= 1; // 从右向左找首个小于基准数的元素
}
while (i < j && nums[i] <= nums[left]) {
i += 1; // 从左向右找首个大于基准数的元素
}
// 元素交换
swap(nums, i, j); // 交换这两个元素
}
swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引
}
[class]{QuickSort}-[func]{partition}
```
=== "C"
@ -202,30 +142,9 @@ comments: true
=== "Swift"
```swift title="quick_sort.swift"
/* 元素交换 */
func swap(nums: inout [Int], i: Int, j: Int) {
let tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
}
[class]{}-[func]{swap}
/* 哨兵划分 */
func partition(nums: inout [Int], left: Int, right: Int) -> Int {
// 以 nums[left] 作为基准数
var i = left
var j = right
while i < j {
while i < j, nums[j] >= nums[left] {
j -= 1 // 从右向左找首个小于基准数的元素
}
while i < j, nums[i] <= nums[left] {
i += 1 // 从左向右找首个大于基准数的元素
}
swap(nums: &nums, i: i, j: j) // 交换这两个元素
}
swap(nums: &nums, i: i, j: left) // 将基准数交换至两子数组的分界线
return i // 返回基准数的索引
}
[class]{}-[func]{partition}
```
=== "Zig"
@ -324,18 +243,7 @@ comments: true
=== "Swift"
```swift title="quick_sort.swift"
/* 快速排序 */
func quickSort(nums: inout [Int], left: Int, right: Int) {
// 子数组长度为 1 时终止递归
if left >= right {
return
}
// 哨兵划分
let pivot = partition(nums: &nums, left: left, right: right)
// 递归左子数组、右子数组
quickSort(nums: &nums, left: left, right: pivot - 1)
quickSort(nums: &nums, left: pivot + 1, right: right)
}
[class]{}-[func]{quickSort}
```
=== "Zig"
@ -475,26 +383,9 @@ comments: true
=== "Swift"
```swift title="quick_sort.swift"
/* 选取三个元素的中位数 */
func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
if (nums[left] < nums[mid]) != (nums[left] < nums[right]) {
return left
} else if (nums[mid] < nums[left]) != (nums[mid] < nums[right]) {
return mid
} else {
return right
}
}
[class]{}-[func]{medianThree}
/* 哨兵划分(三数取中值) */
func partition(nums: inout [Int], left: Int, right: Int) -> Int {
// 选取三个候选元素的中位数
let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)
// 将中位数交换至数组最左端
swap(nums: &nums, i: left, j: med)
// 以 nums[left] 作为基准数
// 下同省略...
}
[class]{}-[func]{partitionMedian}
```
=== "Zig"
@ -595,24 +486,7 @@ comments: true
=== "Swift"
```swift title="quick_sort.swift"
/* 快速排序(尾递归优化) */
func quickSort(nums: inout [Int], left: Int, right: Int) {
var left = left
var right = right
// 子数组长度为 1 时终止
while left < right {
// 哨兵划分操作
let pivot = partition(nums: &nums, left: left, right: right)
// 对两个子数组中较短的那个执行快排
if (pivot - left) < (right - pivot) {
quickSort(nums: &nums, left: left, right: pivot - 1) // 递归排序左子数组
left = pivot + 1 // 剩余待排序区间为 [pivot + 1, right]
} else {
quickSort(nums: &nums, left: pivot + 1, right: right) // 递归排序右子数组
right = pivot - 1 // 剩余待排序区间为 [left, pivot - 1]
}
}
}
[class]{}-[func]{quickSortTailCall}
```
=== "Zig"

@ -432,59 +432,7 @@ comments: true
=== "Swift"
```swift title="linkedlist_queue.swift"
/* 基于链表实现的队列 */
class LinkedListQueue {
private var front: ListNode? // 头结点
private var rear: ListNode? // 尾结点
private var _size = 0
init() {}
/* 获取队列的长度 */
func size() -> Int {
_size
}
/* 判断队列是否为空 */
func isEmpty() -> Bool {
size() == 0
}
/* 入队 */
func push(num: Int) {
// 尾结点后添加 num
let node = ListNode(x: num)
// 如果队列为空,则令头、尾结点都指向该结点
if front == nil {
front = node
rear = node
}
// 如果队列不为空,则将该结点添加到尾结点后
else {
rear?.next = node
rear = node
}
_size += 1
}
/* 出队 */
@discardableResult
func poll() -> Int {
let num = peek()
// 删除头结点
front = front?.next
_size -= 1
return num
}
/* 访问队首元素 */
func peek() -> Int {
if isEmpty() {
fatalError("队列为空")
}
return front!.val
}
}
[class]{LinkedListQueue}-[func]{}
```
=== "Zig"
@ -692,64 +640,7 @@ comments: true
=== "Swift"
```swift title="array_queue.swift"
/* 基于环形数组实现的队列 */
class ArrayQueue {
private var nums: [Int] // 用于存储队列元素的数组
private var front = 0 // 队首指针,指向队首元素
private var queSize = 0 // 队列长度
init(capacity: Int) {
// 初始化数组
nums = Array(repeating: 0, count: capacity)
}
/* 获取队列的容量 */
func capacity() -> Int {
nums.count
}
/* 获取队列的长度 */
func size() -> Int {
queSize
}
/* 判断队列是否为空 */
func isEmpty() -> Bool {
queSize == 0
}
/* 入队 */
func push(num: Int) {
if size() == capacity() {
print("队列已满")
return
}
// 计算尾指针,指向队尾索引 + 1
// 通过取余操作,实现 rear 越过数组尾部后回到头部
let rear = (front + queSize) % capacity()
// 尾结点后添加 num
nums[rear] = num
queSize += 1
}
/* 出队 */
@discardableResult
func poll() -> Int {
let num = peek()
// 队首指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % capacity()
queSize -= 1
return num
}
/* 访问队首元素 */
func peek() -> Int {
if isEmpty() {
fatalError("队列为空")
}
return nums[front]
}
}
[class]{ArrayQueue}-[func]{}
```
=== "Zig"

@ -422,48 +422,7 @@ comments: true
=== "Swift"
```swift title="linkedlist_stack.swift"
/* 基于链表实现的栈 */
class LinkedListStack {
private var _peek: ListNode? // 将头结点作为栈顶
private var _size = 0 // 栈的长度
init() {}
/* 获取栈的长度 */
func size() -> Int {
_size
}
/* 判断栈是否为空 */
func isEmpty() -> Bool {
size() == 0
}
/* 入栈 */
func push(num: Int) {
let node = ListNode(x: num)
node.next = _peek
_peek = node
_size += 1
}
/* 出栈 */
@discardableResult
func pop() -> Int {
let num = peek()
_peek = _peek?.next
_size -= 1
return num
}
/* 访问栈顶元素 */
func peek() -> Int {
if isEmpty() {
fatalError("栈为空")
}
return _peek!.val
}
}
[class]{LinkedListStack}-[func]{}
```
=== "Zig"
@ -624,47 +583,7 @@ comments: true
=== "Swift"
```swift title="array_stack.swift"
/* 基于数组实现的栈 */
class ArrayStack {
private var stack: [Int]
init() {
// 初始化列表(动态数组)
stack = []
}
/* 获取栈的长度 */
func size() -> Int {
stack.count
}
/* 判断栈是否为空 */
func isEmpty() -> Bool {
stack.isEmpty
}
/* 入栈 */
func push(num: Int) {
stack.append(num)
}
/* 出栈 */
@discardableResult
func pop() -> Int {
if isEmpty() {
fatalError("栈为空")
}
return stack.removeLast()
}
/* 访问栈顶元素 */
func peek() -> Int {
if isEmpty() {
fatalError("栈为空")
}
return stack.last!
}
}
[class]{ArrayStack}-[func]{}
```
=== "Zig"

@ -362,13 +362,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "Swift"
```swift title="avl_tree.swift"
/* 获取平衡因子 */
func balanceFactor(node: TreeNode?) -> Int {
// 空结点平衡因子为 0
guard let node = node else { return 0 }
// 结点平衡因子 = 左子树高度 - 右子树高度
return height(node: node.left) - height(node: node.right)
}
[class]{AVLTree}-[func]{balanceFactor}
```
=== "Zig"
@ -485,19 +479,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "Swift"
```swift title="avl_tree.swift"
/* 右旋操作 */
func rightRotate(node: TreeNode?) -> TreeNode? {
let child = node?.left
let grandChild = child?.right
// 以 child 为原点,将 node 向右旋转
child?.right = node
node?.left = grandChild
// 更新结点高度
updateHeight(node: node)
updateHeight(node: child)
// 返回旋转后子树的根结点
return child
}
[class]{AVLTree}-[func]{rightRotate}
```
=== "Zig"
@ -596,20 +578,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "Swift"
```swift title="avl_tree.swift"
/* 左旋操作 */
func leftRotate(node: TreeNode?) -> TreeNode? {
let child = node?.right
let grandChild = child?.left
// 以 child 为原点,将 node 向左旋转
child?.left = node
node?.right = grandChild
// 更新结点高度
updateHeight(node: node)
updateHeight(node: child)
// 返回旋转后子树的根结点
return child
}
[class]{AVLTree}-[func]{leftRotate}
```
=== "Zig"
@ -768,35 +737,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "Swift"
```swift title="avl_tree.swift"
/* 执行旋转操作,使该子树重新恢复平衡 */
func rotate(node: TreeNode?) -> TreeNode? {
// 获取结点 node 的平衡因子
let balanceFactor = balanceFactor(node: node)
// 左偏树
if balanceFactor > 1 {
if self.balanceFactor(node: node?.left) >= 0 {
// 右旋
return rightRotate(node: node)
} else {
// 先左旋后右旋
node?.left = leftRotate(node: node?.left)
return rightRotate(node: node)
}
}
// 右偏树
if balanceFactor < -1 {
if self.balanceFactor(node: node?.right) <= 0 {
// 左旋
return leftRotate(node: node)
} else {
// 先右旋后左旋
node?.right = rightRotate(node: node?.right)
return leftRotate(node: node)
}
}
// 平衡树,无需旋转,直接返回
return node
}
[class]{AVLTree}-[func]{rotate}
```
=== "Zig"

@ -120,27 +120,7 @@ comments: true
=== "Swift"
```swift title="binary_search_tree.swift"
/* 查找结点 */
func search(num: Int) -> TreeNode? {
var cur = root
// 循环查找,越过叶结点后跳出
while cur != nil {
// 目标结点在 cur 的右子树中
if cur!.val < num {
cur = cur?.right
}
// 目标结点在 cur 的左子树中
else if cur!.val > num {
cur = cur?.left
}
// 找到目标结点,跳出循环
else {
break
}
}
// 返回目标结点
return cur
}
[class]{BinarySearchTree}-[func]{search}
```
=== "Zig"
@ -266,39 +246,7 @@ comments: true
=== "Swift"
```swift title="binary_search_tree.swift"
/* 插入结点 */
func insert(num: Int) -> TreeNode? {
// 若树为空,直接提前返回
if root == nil {
return nil
}
var cur = root
var pre: TreeNode?
// 循环查找,越过叶结点后跳出
while cur != nil {
// 找到重复结点,直接返回
if cur!.val == num {
return nil
}
pre = cur
// 插入位置在 cur 的右子树中
if cur!.val < num {
cur = cur?.right
}
// 插入位置在 cur 的左子树中
else {
cur = cur?.left
}
}
// 插入结点 val
let node = TreeNode(x: num)
if pre!.val < num {
pre?.right = node
} else {
pre?.left = node
}
return node
}
[class]{BinarySearchTree}-[func]{insert}
```
=== "Zig"
@ -530,71 +478,9 @@ comments: true
=== "Swift"
```swift title="binary_search_tree.swift"
/* 删除结点 */
@discardableResult
func remove(num: Int) -> TreeNode? {
// 若树为空,直接提前返回
if root == nil {
return nil
}
var cur = root
var pre: TreeNode?
// 循环查找,越过叶结点后跳出
while cur != nil {
// 找到待删除结点,跳出循环
if cur!.val == num {
break
}
pre = cur
// 待删除结点在 cur 的右子树中
if cur!.val < num {
cur = cur?.right
}
// 待删除结点在 cur 的左子树中
else {
cur = cur?.left
}
}
// 若无待删除结点,则直接返回
if cur == nil {
return nil
}
// 子结点数量 = 0 or 1
if cur?.left == nil || cur?.right == nil {
// 当子结点数量 = 0 / 1 时, child = null / 该子结点
let child = cur?.left != nil ? cur?.left : cur?.right
// 删除结点 cur
if pre?.left === cur {
pre?.left = child
} else {
pre?.right = child
}
}
// 子结点数量 = 2
else {
// 获取中序遍历中 cur 的下一个结点
let nex = getInOrderNext(root: cur?.right)
let tmp = nex!.val
// 递归删除结点 nex
remove(num: nex!.val)
// 将 nex 的值复制给 cur
cur?.val = tmp
}
return cur
}
[class]{BinarySearchTree}-[func]{remove}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
func getInOrderNext(root: TreeNode?) -> TreeNode? {
var root = root
if root == nil {
return root
}
// 循环访问左子结点,直到叶结点时为最小结点,跳出
while root?.left != nil {
root = root?.left
}
return root
}
[class]{BinarySearchTree}-[func]{getInOrderNext}
```
=== "Zig"

@ -110,24 +110,7 @@ comments: true
=== "Swift"
```swift title="binary_tree_bfs.swift"
/* 层序遍历 */
func hierOrder(root: TreeNode) -> [Int] {
// 初始化队列,加入根结点
var queue: [TreeNode] = [root]
// 初始化一个列表,用于保存遍历序列
var list: [Int] = []
while !queue.isEmpty {
let node = queue.removeFirst() // 队列出队
list.append(node.val) // 保存结点值
if let left = node.left {
queue.append(left) // 左子结点入队
}
if let right = node.right {
queue.append(right) // 右子结点入队
}
}
return list
}
[class]{}-[func]{hierOrder}
```
=== "Zig"
@ -286,38 +269,11 @@ comments: true
=== "Swift"
```swift title="binary_tree_dfs.swift"
/* 前序遍历 */
func preOrder(root: TreeNode?) {
guard let root = root else {
return
}
// 访问优先级:根结点 -> 左子树 -> 右子树
list.append(root.val)
preOrder(root: root.left)
preOrder(root: root.right)
}
[class]{}-[func]{preOrder}
/* 中序遍历 */
func inOrder(root: TreeNode?) {
guard let root = root else {
return
}
// 访问优先级:左子树 -> 根结点 -> 右子树
inOrder(root: root.left)
list.append(root.val)
inOrder(root: root.right)
}
[class]{}-[func]{inOrder}
/* 后序遍历 */
func postOrder(root: TreeNode?) {
guard let root = root else {
return
}
// 访问优先级:左子树 -> 右子树 -> 根结点
postOrder(root: root.left)
postOrder(root: root.right)
list.append(root.val)
}
[class]{}-[func]{postOrder}
```
=== "Zig"

@ -14,6 +14,7 @@ from docs.utils.extract_code_python import ExtractCodeBlocksPython
from docs.utils.extract_code_java import ExtractCodeBlocksJava
from docs.utils.extract_code_cpp import ExtractCodeBlocksCpp
from docs.utils.extract_code_jsts import ExtractCodeBlocksJSTS
from docs.utils.extract_code_swift import ExtractCodeBlocksSwift
def build_markdown(md_path):
@ -88,6 +89,7 @@ extractor_dict = {
"cpp": ExtractCodeBlocksCpp(),
"javascript": ExtractCodeBlocksJSTS(),
"typescript": ExtractCodeBlocksJSTS(),
"swift": ExtractCodeBlocksSwift(),
}

@ -1,5 +1,5 @@
"""
File: extract_code_python.py
File: extract_code_cpp.py
Created Time: 2023-02-07
Author: Krahets (krahets@163.com)
"""

@ -1,5 +1,5 @@
"""
File: extract_code_python.py
File: extract_code_java.py
Created Time: 2023-02-07
Author: Krahets (krahets@163.com)
"""

@ -1,5 +1,5 @@
"""
File: extract_code_python.py
File: extract_code_jsts.py
Created Time: 2023-02-07
Author: Krahets (krahets@163.com)
"""
@ -17,10 +17,10 @@ class ExtractCodeBlocksJSTS(ExtractCodeBlocksJava):
# Pattern to match function names and class names
self.func_pattern = r'(\s*)(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(.*)\s+{\s*\n'
self.class_pattern = r'class\s+(\w+)\s*\{'
self.class_pattern = r'(public|)\s*class\s+(\w+)\s*\{'
self.func_pattern_keys = ["total", "ind", "prefix", "label", ":", "return"]
self.class_pattern_keys = ["total", "label"]
self.class_pattern_keys = ["total", "scope", "label"]
# for code_path in glob.glob("codes/cpp/chapter_*/my_heap.cpp"):

@ -0,0 +1,28 @@
"""
File: extract_code_swift.py
Created Time: 2023-02-08
Author: Krahets (krahets@163.com)
"""
import re
import glob
import sys, os.path as osp
sys.path.append(osp.dirname(osp.dirname(osp.dirname(osp.abspath(__file__)))))
from docs.utils.extract_code_java import ExtractCodeBlocksJava
class ExtractCodeBlocksSwift(ExtractCodeBlocksJava):
def __init__(self) -> None:
super().__init__()
# Pattern to match function names and class names
self.func_pattern = r'(\s*)(public|private|)\s*(static|)\s*(func|)\s*(\w+)\(.*\).+{\s*\n'
self.class_pattern = r'(public|)\s*class\s+(\w+)\s*\{'
self.func_pattern_keys = ["total", "ind", "scope", "static", "func", "label"]
self.class_pattern_keys = ["total", "scope", "label"]
# for code_path in glob.glob("codes/cpp/chapter_*/my_heap.cpp"):
# ext = ExtractCodeBlocksCpp()
# ext.extract(code_path)
Loading…
Cancel
Save