mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 09:56:28 +08:00
Add build script for Swift.
This commit is contained in:
parent
05f0054005
commit
38751cc5f5
25 changed files with 128 additions and 1223 deletions
|
@ -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] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
var i = left
|
var i = left
|
||||||
var j = right
|
var j = right
|
||||||
|
@ -30,22 +30,23 @@ func quickSortPartition(nums: inout [Int], left: Int, right: Int) -> Int {
|
||||||
return i // 返回基准数的索引
|
return i // 返回基准数的索引
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快速排序类-快速排序
|
/* 快速排序 */
|
||||||
func quickSort(nums: inout [Int], left: Int, right: Int) {
|
func quickSort(nums: inout [Int], left: Int, right: Int) {
|
||||||
// 子数组长度为 1 时终止递归
|
// 子数组长度为 1 时终止递归
|
||||||
if left >= right {
|
if left >= right {
|
||||||
return
|
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: left, right: pivot - 1)
|
||||||
quickSort(nums: &nums, left: pivot + 1, right: right)
|
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]) {
|
if (nums[left] < nums[mid]) != (nums[left] < nums[right]) {
|
||||||
return left
|
return left
|
||||||
} else if (nums[mid] < nums[left]) != (nums[mid] < nums[right]) {
|
} 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)
|
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) {
|
func quickSortMedian(nums: inout [Int], left: Int, right: Int) {
|
||||||
// 子数组长度为 1 时终止递归
|
// 子数组长度为 1 时终止递归
|
||||||
if left >= right {
|
if left >= right {
|
||||||
return
|
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: left, right: pivot - 1)
|
||||||
quickSortMedian(nums: &nums, left: pivot + 1, right: right)
|
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) {
|
func quickSortTailCall(nums: inout [Int], left: Int, right: Int) {
|
||||||
var left = left
|
var left = left
|
||||||
var right = right
|
var right = right
|
||||||
// 子数组长度为 1 时终止
|
// 子数组长度为 1 时终止
|
||||||
while left < right {
|
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) {
|
if (pivot - left) < (right - pivot) {
|
||||||
quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // 递归排序左子数组
|
quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // 递归排序左子数组
|
||||||
|
|
|
@ -181,14 +181,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array.swift"
|
```swift title="array.swift"
|
||||||
/* 随机返回一个数组元素 */
|
[class]{}-[func]{randomAccess}
|
||||||
func randomAccess(nums: [Int]) -> Int {
|
|
||||||
// 在区间 [0, nums.count) 中随机抽取一个数字
|
|
||||||
let randomIndex = nums.indices.randomElement()!
|
|
||||||
// 获取并返回随机元素
|
|
||||||
let randomNum = nums[randomIndex]
|
|
||||||
return randomNum
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -281,17 +274,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array.swift"
|
```swift title="array.swift"
|
||||||
/* 扩展数组长度 */
|
[class]{}-[func]{extend}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -415,24 +398,9 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array.swift"
|
```swift title="array.swift"
|
||||||
/* 在数组的索引 index 处插入元素 num */
|
[class]{}-[func]{insert}
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 删除索引 index 处元素 */
|
[class]{}-[func]{remove}
|
||||||
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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -539,18 +507,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array.swift"
|
```swift title="array.swift"
|
||||||
/* 遍历数组 */
|
[class]{}-[func]{traverse}
|
||||||
func traverse(nums: [Int]) {
|
|
||||||
var count = 0
|
|
||||||
// 通过索引遍历数组
|
|
||||||
for _ in nums.indices {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
// 直接遍历数组
|
|
||||||
for _ in nums {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -644,15 +601,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array.swift"
|
```swift title="array.swift"
|
||||||
/* 在数组中查找指定元素 */
|
[class]{}-[func]{find}
|
||||||
func find(nums: [Int], target: Int) -> Int {
|
|
||||||
for i in nums.indices {
|
|
||||||
if nums[i] == target {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -572,17 +572,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linked_list.swift"
|
```swift title="linked_list.swift"
|
||||||
/* 访问链表中索引为 index 的结点 */
|
[class]{}-[func]{access}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -680,19 +670,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linked_list.swift"
|
```swift title="linked_list.swift"
|
||||||
/* 在链表中查找值为 target 的首个结点 */
|
[class]{}-[func]{find}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -956,99 +956,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_list.swift"
|
```swift title="my_list.swift"
|
||||||
/* 列表类简易实现 */
|
[class]{MyList}-[func]{}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -665,22 +665,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 常数阶 */
|
[class]{}-[func]{constant}
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -797,15 +782,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 线性阶 */
|
[class]{}-[func]{linear}
|
||||||
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)") })
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -901,14 +878,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 线性阶(递归实现) */
|
[class]{}-[func]{linearRecur}
|
||||||
func linearRecur(n: Int) {
|
|
||||||
print("递归 n = \(n)")
|
|
||||||
if n == 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
linearRecur(n: n - 1)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1004,11 +974,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 平方阶 */
|
[class]{}-[func]{quadratic}
|
||||||
func quadratic(n: Int) {
|
|
||||||
// 二维列表占用 O(n^2) 空间
|
|
||||||
let numList = Array(repeating: Array(repeating: 0, count: n), count: n)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1100,15 +1066,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 平方阶(递归实现) */
|
[class]{}-[func]{quadraticRecur}
|
||||||
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)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1199,16 +1157,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="space_complexity.swift"
|
```swift title="space_complexity.swift"
|
||||||
/* 指数阶(建立满二叉树) */
|
[class]{}-[func]{buildTree}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -108,17 +108,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="leetcode_two_sum.swift"
|
```swift title="leetcode_two_sum.swift"
|
||||||
func twoSumBruteForce(nums: [Int], target: Int) -> [Int] {
|
[class]{}-[func]{twoSumBruteForce}
|
||||||
// 两层循环,时间复杂度 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]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -229,18 +219,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="leetcode_two_sum.swift"
|
```swift title="leetcode_two_sum.swift"
|
||||||
func twoSumHashTable(nums: [Int], target: Int) -> [Int] {
|
[class]{}-[func]{twoSumHashTable}
|
||||||
// 辅助哈希表,空间复杂度 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]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -868,15 +868,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 常数阶 */
|
[class]{}-[func]{constant}
|
||||||
func constant(n: Int) -> Int {
|
|
||||||
var count = 0
|
|
||||||
let size = 100000
|
|
||||||
for _ in 0 ..< size {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -971,14 +963,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 线性阶 */
|
[class]{}-[func]{linear}
|
||||||
func linear(n: Int) -> Int {
|
|
||||||
var count = 0
|
|
||||||
for _ in 0 ..< n {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1078,15 +1063,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 线性阶(遍历数组) */
|
[class]{}-[func]{arrayTraversal}
|
||||||
func arrayTraversal(nums: [Int]) -> Int {
|
|
||||||
var count = 0
|
|
||||||
// 循环次数与数组长度成正比
|
|
||||||
for _ in nums {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1191,17 +1168,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 平方阶 */
|
[class]{}-[func]{quadratic}
|
||||||
func quadratic(n: Int) -> Int {
|
|
||||||
var count = 0
|
|
||||||
// 循环次数与数组长度成平方关系
|
|
||||||
for _ in 0 ..< n {
|
|
||||||
for _ in 0 ..< n {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1341,24 +1308,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 平方阶(冒泡排序) */
|
[class]{}-[func]{bubbleSort}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1485,20 +1435,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 指数阶(循环实现) */
|
[class]{}-[func]{exponential}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1594,13 +1531,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 指数阶(递归实现) */
|
[class]{}-[func]{expRecur}
|
||||||
func expRecur(n: Int) -> Int {
|
|
||||||
if n == 1 {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return expRecur(n: n - 1) + expRecur(n: n - 1) + 1
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1698,16 +1629,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 对数阶(循环实现) */
|
[class]{}-[func]{logarithmic}
|
||||||
func logarithmic(n: Int) -> Int {
|
|
||||||
var count = 0
|
|
||||||
var n = n
|
|
||||||
while n > 1 {
|
|
||||||
n = n / 2
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1799,13 +1721,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 对数阶(递归实现) */
|
[class]{}-[func]{logRecur}
|
||||||
func logRecur(n: Int) -> Int {
|
|
||||||
if n <= 1 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return logRecur(n: n / 2) + 1
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1907,17 +1823,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 线性对数阶 */
|
[class]{}-[func]{linearLogRecur}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -2032,18 +1938,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="time_complexity.swift"
|
```swift title="time_complexity.swift"
|
||||||
/* 阶乘阶(递归实现) */
|
[class]{}-[func]{factorialRecur}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -572,55 +572,9 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array_hash_map.swift"
|
```swift title="array_hash_map.swift"
|
||||||
/* 键值对 int->String */
|
[class]{Entry}-[func]{}
|
||||||
class Entry {
|
|
||||||
var key: Int
|
[class]{ArrayHashMap}-[func]{}
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 删除操作 */
|
|
||||||
func remove(key: Int) {
|
|
||||||
let index = hashFunc(key: key)
|
|
||||||
// 置为 nil ,代表删除
|
|
||||||
bucket[index] = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -350,27 +350,11 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_heap.swift"
|
```swift title="my_heap.swift"
|
||||||
var maxHeap: [Int]
|
[class]{MaxHeap}-[func]{left}
|
||||||
|
|
||||||
/* 构造函数,建立空堆 */
|
[class]{MaxHeap}-[func]{right}
|
||||||
init() {
|
|
||||||
maxHeap = []
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 获取左子结点索引 */
|
[class]{MaxHeap}-[func]{parent}
|
||||||
func left(i: Int) -> Int {
|
|
||||||
2 * i + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 获取右子结点索引 */
|
|
||||||
func right(i: Int) -> Int {
|
|
||||||
2 * i + 2
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 获取父结点索引 */
|
|
||||||
func parent(i: Int) -> Int {
|
|
||||||
(i - 1) / 2 // 向下整除
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -437,10 +421,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_heap.swift"
|
```swift title="my_heap.swift"
|
||||||
/* 访问堆顶元素 */
|
[class]{MaxHeap}-[func]{peek}
|
||||||
func peek() -> Int {
|
|
||||||
maxHeap[0]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -556,30 +537,9 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_heap.swift"
|
```swift title="my_heap.swift"
|
||||||
/* 元素入堆 */
|
[class]{MaxHeap}-[func]{push}
|
||||||
func push(val: Int) {
|
|
||||||
// 添加结点
|
|
||||||
maxHeap.append(val)
|
|
||||||
// 从底至顶堆化
|
|
||||||
siftUp(i: size() - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 从结点 i 开始,从底至顶堆化 */
|
[class]{MaxHeap}-[func]{siftUp}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -728,46 +688,9 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_heap.swift"
|
```swift title="my_heap.swift"
|
||||||
/* 元素出堆 */
|
[class]{MaxHeap}-[func]{poll}
|
||||||
func poll() -> Int {
|
|
||||||
// 判空处理
|
|
||||||
if isEmpty() {
|
|
||||||
fatalError("堆为空")
|
|
||||||
}
|
|
||||||
// 交换根结点与最右叶结点(即交换首元素与尾元素)
|
|
||||||
swap(i: 0, j: size() - 1)
|
|
||||||
// 删除结点
|
|
||||||
let val = maxHeap.remove(at: size() - 1)
|
|
||||||
// 从顶至底堆化
|
|
||||||
siftDown(i: 0)
|
|
||||||
// 返回堆顶元素
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 从结点 i 开始,从顶至底堆化 */
|
[class]{MaxHeap}-[func]{siftDown}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -842,15 +765,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="my_heap.swift"
|
```swift title="my_heap.swift"
|
||||||
/* 构造函数,根据输入列表建堆 */
|
[class]{MaxHeap}-[func]{init}
|
||||||
init(nums: [Int]) {
|
|
||||||
// 将列表元素原封不动添加进堆
|
|
||||||
maxHeap = nums
|
|
||||||
// 堆化除叶结点以外的其他所有结点
|
|
||||||
for i in stride(from: parent(i: size() - 1), through: 0, by: -1) {
|
|
||||||
siftDown(i: i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -137,25 +137,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_search.swift"
|
```swift title="binary_search.swift"
|
||||||
/* 二分查找(双闭区间) */
|
[class]{}-[func]{binarySearch}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -254,25 +236,7 @@ $$
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_search.swift"
|
```swift title="binary_search.swift"
|
||||||
/* 二分查找(左闭右开) */
|
[class]{}-[func]{binarySearch1}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -82,12 +82,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="hashing_search.swift"
|
```swift title="hashing_search.swift"
|
||||||
/* 哈希查找(数组) */
|
[class]{}-[func]{hashingSearchArray}
|
||||||
func hashingSearchArray(map: [Int: Int], target: Int) -> Int {
|
|
||||||
// 哈希表的 key: 目标元素,value: 索引
|
|
||||||
// 若哈希表中无此 key ,返回 -1
|
|
||||||
return map[target, default: -1]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -167,12 +162,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="hashing_search.swift"
|
```swift title="hashing_search.swift"
|
||||||
/* 哈希查找(链表) */
|
[class]{}-[func]{hashingSearchLinkedList}
|
||||||
func hashingSearchLinkedList(map: [Int: ListNode], target: Int) -> ListNode? {
|
|
||||||
// 哈希表的 key: 目标结点值,value: 结点对象
|
|
||||||
// 若哈希表中无此 key ,返回 null
|
|
||||||
return map[target]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -87,18 +87,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linear_search.swift"
|
```swift title="linear_search.swift"
|
||||||
/* 线性查找(数组) */
|
[class]{}-[func]{linearSearchArray}
|
||||||
func linearSearchArray(nums: [Int], target: Int) -> Int {
|
|
||||||
// 遍历数组
|
|
||||||
for i in nums.indices {
|
|
||||||
// 找到目标元素,返回其索引
|
|
||||||
if nums[i] == target {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 未找到目标元素,返回 -1
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -185,20 +174,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linear_search.swift"
|
```swift title="linear_search.swift"
|
||||||
/* 线性查找(链表) */
|
[class]{}-[func]{linearSearchLinkedList}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -144,21 +144,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="bubble_sort.swift"
|
```swift title="bubble_sort.swift"
|
||||||
/* 冒泡排序 */
|
[class]{}-[func]{bubbleSort}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -293,25 +279,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="bubble_sort.swift"
|
```swift title="bubble_sort.swift"
|
||||||
/* 冒泡排序(标志优化)*/
|
[class]{}-[func]{bubbleSortWithFlag}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -119,20 +119,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="insertion_sort.swift"
|
```swift title="insertion_sort.swift"
|
||||||
/* 插入排序 */
|
[class]{}-[func]{insertionSort}
|
||||||
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 赋值到正确位置
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -54,27 +54,9 @@ comments: true
|
||||||
=== "C++"
|
=== "C++"
|
||||||
|
|
||||||
```cpp title="quick_sort.cpp"
|
```cpp title="quick_sort.cpp"
|
||||||
/* 元素交换 */
|
[class]{QuickSort}-[func]{swap}
|
||||||
void swap(vector<int>& nums, int i, int j) {
|
|
||||||
int tmp = nums[i];
|
|
||||||
nums[i] = nums[j];
|
|
||||||
nums[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 哨兵划分 */
|
[class]{QuickSort}-[func]{partition}
|
||||||
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; // 返回基准数的索引
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Python"
|
=== "Python"
|
||||||
|
@ -109,59 +91,17 @@ comments: true
|
||||||
=== "JavaScript"
|
=== "JavaScript"
|
||||||
|
|
||||||
```javascript title="quick_sort.js"
|
```javascript title="quick_sort.js"
|
||||||
/* 元素交换 */
|
[class]{QuickSort}-[func]{swap}
|
||||||
function swap(nums, i, j) {
|
|
||||||
let tmp = nums[i];
|
[class]{QuickSort}-[func]{partition}
|
||||||
nums[i] = nums[j];
|
|
||||||
nums[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 哨兵划分 */
|
|
||||||
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; // 返回基准数的索引
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TypeScript"
|
=== "TypeScript"
|
||||||
|
|
||||||
```typescript title="quick_sort.ts"
|
```typescript title="quick_sort.ts"
|
||||||
/* 元素交换 */
|
[class]{QuickSort}-[func]{swap}
|
||||||
function swap(nums: number[], i: number, j: number): void {
|
|
||||||
let tmp = nums[i];
|
|
||||||
nums[i] = nums[j];
|
|
||||||
nums[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 哨兵划分 */
|
[class]{QuickSort}-[func]{partition}
|
||||||
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; // 返回基准数的索引
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -202,30 +142,9 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="quick_sort.swift"
|
```swift title="quick_sort.swift"
|
||||||
/* 元素交换 */
|
[class]{}-[func]{swap}
|
||||||
func swap(nums: inout [Int], i: Int, j: Int) {
|
|
||||||
let tmp = nums[i]
|
|
||||||
nums[i] = nums[j]
|
|
||||||
nums[j] = tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 哨兵划分 */
|
[class]{}-[func]{partition}
|
||||||
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 // 返回基准数的索引
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -324,18 +243,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="quick_sort.swift"
|
```swift title="quick_sort.swift"
|
||||||
/* 快速排序 */
|
[class]{}-[func]{quickSort}
|
||||||
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)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -475,26 +383,9 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="quick_sort.swift"
|
```swift title="quick_sort.swift"
|
||||||
/* 选取三个元素的中位数 */
|
[class]{}-[func]{medianThree}
|
||||||
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]{partitionMedian}
|
||||||
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] 作为基准数
|
|
||||||
// 下同省略...
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -595,24 +486,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="quick_sort.swift"
|
```swift title="quick_sort.swift"
|
||||||
/* 快速排序(尾递归优化) */
|
[class]{}-[func]{quickSortTailCall}
|
||||||
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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -432,59 +432,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linkedlist_queue.swift"
|
```swift title="linkedlist_queue.swift"
|
||||||
/* 基于链表实现的队列 */
|
[class]{LinkedListQueue}-[func]{}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -692,64 +640,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array_queue.swift"
|
```swift title="array_queue.swift"
|
||||||
/* 基于环形数组实现的队列 */
|
[class]{ArrayQueue}-[func]{}
|
||||||
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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -422,48 +422,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="linkedlist_stack.swift"
|
```swift title="linkedlist_stack.swift"
|
||||||
/* 基于链表实现的栈 */
|
[class]{LinkedListStack}-[func]{}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -624,47 +583,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="array_stack.swift"
|
```swift title="array_stack.swift"
|
||||||
/* 基于数组实现的栈 */
|
[class]{ArrayStack}-[func]{}
|
||||||
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!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -362,13 +362,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="avl_tree.swift"
|
```swift title="avl_tree.swift"
|
||||||
/* 获取平衡因子 */
|
[class]{AVLTree}-[func]{balanceFactor}
|
||||||
func balanceFactor(node: TreeNode?) -> Int {
|
|
||||||
// 空结点平衡因子为 0
|
|
||||||
guard let node = node else { return 0 }
|
|
||||||
// 结点平衡因子 = 左子树高度 - 右子树高度
|
|
||||||
return height(node: node.left) - height(node: node.right)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -485,19 +479,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="avl_tree.swift"
|
```swift title="avl_tree.swift"
|
||||||
/* 右旋操作 */
|
[class]{AVLTree}-[func]{rightRotate}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -596,20 +578,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="avl_tree.swift"
|
```swift title="avl_tree.swift"
|
||||||
/* 左旋操作 */
|
[class]{AVLTree}-[func]{leftRotate}
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -768,35 +737,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="avl_tree.swift"
|
```swift title="avl_tree.swift"
|
||||||
/* 执行旋转操作,使该子树重新恢复平衡 */
|
[class]{AVLTree}-[func]{rotate}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -120,27 +120,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_search_tree.swift"
|
```swift title="binary_search_tree.swift"
|
||||||
/* 查找结点 */
|
[class]{BinarySearchTree}-[func]{search}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -266,39 +246,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_search_tree.swift"
|
```swift title="binary_search_tree.swift"
|
||||||
/* 插入结点 */
|
[class]{BinarySearchTree}-[func]{insert}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -530,71 +478,9 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_search_tree.swift"
|
```swift title="binary_search_tree.swift"
|
||||||
/* 删除结点 */
|
[class]{BinarySearchTree}-[func]{remove}
|
||||||
@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
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
|
[class]{BinarySearchTree}-[func]{getInOrderNext}
|
||||||
func getInOrderNext(root: TreeNode?) -> TreeNode? {
|
|
||||||
var root = root
|
|
||||||
if root == nil {
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
// 循环访问左子结点,直到叶结点时为最小结点,跳出
|
|
||||||
while root?.left != nil {
|
|
||||||
root = root?.left
|
|
||||||
}
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
|
|
@ -110,24 +110,7 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_tree_bfs.swift"
|
```swift title="binary_tree_bfs.swift"
|
||||||
/* 层序遍历 */
|
[class]{}-[func]{hierOrder}
|
||||||
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
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -286,38 +269,11 @@ comments: true
|
||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="binary_tree_dfs.swift"
|
```swift title="binary_tree_dfs.swift"
|
||||||
/* 前序遍历 */
|
[class]{}-[func]{preOrder}
|
||||||
func preOrder(root: TreeNode?) {
|
|
||||||
guard let root = root else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 访问优先级:根结点 -> 左子树 -> 右子树
|
|
||||||
list.append(root.val)
|
|
||||||
preOrder(root: root.left)
|
|
||||||
preOrder(root: root.right)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 中序遍历 */
|
[class]{}-[func]{inOrder}
|
||||||
func inOrder(root: TreeNode?) {
|
|
||||||
guard let root = root else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 访问优先级:左子树 -> 根结点 -> 右子树
|
|
||||||
inOrder(root: root.left)
|
|
||||||
list.append(root.val)
|
|
||||||
inOrder(root: root.right)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 后序遍历 */
|
[class]{}-[func]{postOrder}
|
||||||
func postOrder(root: TreeNode?) {
|
|
||||||
guard let root = root else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 访问优先级:左子树 -> 右子树 -> 根结点
|
|
||||||
postOrder(root: root.left)
|
|
||||||
postOrder(root: root.right)
|
|
||||||
list.append(root.val)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "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_java import ExtractCodeBlocksJava
|
||||||
from docs.utils.extract_code_cpp import ExtractCodeBlocksCpp
|
from docs.utils.extract_code_cpp import ExtractCodeBlocksCpp
|
||||||
from docs.utils.extract_code_jsts import ExtractCodeBlocksJSTS
|
from docs.utils.extract_code_jsts import ExtractCodeBlocksJSTS
|
||||||
|
from docs.utils.extract_code_swift import ExtractCodeBlocksSwift
|
||||||
|
|
||||||
|
|
||||||
def build_markdown(md_path):
|
def build_markdown(md_path):
|
||||||
|
@ -88,6 +89,7 @@ extractor_dict = {
|
||||||
"cpp": ExtractCodeBlocksCpp(),
|
"cpp": ExtractCodeBlocksCpp(),
|
||||||
"javascript": ExtractCodeBlocksJSTS(),
|
"javascript": ExtractCodeBlocksJSTS(),
|
||||||
"typescript": ExtractCodeBlocksJSTS(),
|
"typescript": ExtractCodeBlocksJSTS(),
|
||||||
|
"swift": ExtractCodeBlocksSwift(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
File: extract_code_python.py
|
File: extract_code_cpp.py
|
||||||
Created Time: 2023-02-07
|
Created Time: 2023-02-07
|
||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
File: extract_code_python.py
|
File: extract_code_java.py
|
||||||
Created Time: 2023-02-07
|
Created Time: 2023-02-07
|
||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
File: extract_code_python.py
|
File: extract_code_jsts.py
|
||||||
Created Time: 2023-02-07
|
Created Time: 2023-02-07
|
||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
@ -17,10 +17,10 @@ class ExtractCodeBlocksJSTS(ExtractCodeBlocksJava):
|
||||||
|
|
||||||
# Pattern to match function names and class names
|
# Pattern to match function names and class names
|
||||||
self.func_pattern = r'(\s*)(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(.*)\s+{\s*\n'
|
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.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"):
|
# for code_path in glob.glob("codes/cpp/chapter_*/my_heap.cpp"):
|
||||||
|
|
28
docs/utils/extract_code_swift.py
Normal file
28
docs/utils/extract_code_swift.py
Normal file
|
@ -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…
Reference in a new issue