mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-12 07:26:07 +00:00
Review Swift codes (#1150)
* feat(swift): review for chapter_computational_complexity * feat(swift): review for chapter_data_structure * feat(swift): review for chapter_array_and_linkedlist * feat(swift): review for chapter_stack_and_queue * feat(swift): review for chapter_hashing * feat(swift): review for chapter_tree * feat(swift): add codes for heap article * feat(swift): review for chapter_heap * feat(swift): review for chapter_graph * feat(swift): review for chapter_searching * feat(swift): review for chapter_sorting * feat(swift): review for chapter_divide_and_conquer * feat(swift): review for chapter_backtracking * feat(swift): review for chapter_dynamic_programming * feat(swift): review for chapter_greedy * feat(swift): review for utils * feat(swift): update ci tool * feat(swift): trailing closure * feat(swift): array init * feat(swift): map index
This commit is contained in:
@@ -7,14 +7,12 @@
|
||||
/* 冒泡排序 */
|
||||
func bubbleSort(nums: inout [Int]) {
|
||||
// 外循环:未排序区间为 [0, i]
|
||||
for i in stride(from: nums.count - 1, to: 0, by: -1) {
|
||||
for i in nums.indices.dropFirst().reversed() {
|
||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||
for j in stride(from: 0, to: i, by: 1) {
|
||||
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
|
||||
nums.swapAt(j, j + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,14 +21,12 @@ func bubbleSort(nums: inout [Int]) {
|
||||
/* 冒泡排序(标志优化)*/
|
||||
func bubbleSortWithFlag(nums: inout [Int]) {
|
||||
// 外循环:未排序区间为 [0, i]
|
||||
for i in stride(from: nums.count - 1, to: 0, by: -1) {
|
||||
for i in nums.indices.dropFirst().reversed() {
|
||||
var flag = false // 初始化标志位
|
||||
for j in stride(from: 0, to: i, by: 1) {
|
||||
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
|
||||
nums.swapAt(j, j + 1)
|
||||
flag = true // 记录交换元素
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func bucketSort(nums: inout [Double]) {
|
||||
for bucket in buckets {
|
||||
for num in bucket {
|
||||
nums[i] = num
|
||||
nums.formIndex(after: &i)
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ func countingSortNaive(nums: inout [Int]) {
|
||||
}
|
||||
// 3. 遍历 counter ,将各元素填入原数组 nums
|
||||
var i = 0
|
||||
for num in stride(from: 0, to: m + 1, by: 1) {
|
||||
for _ in stride(from: 0, to: counter[num], by: 1) {
|
||||
for num in 0 ..< m + 1 {
|
||||
for _ in 0 ..< counter[num] {
|
||||
nums[i] = num
|
||||
i += 1
|
||||
}
|
||||
@@ -38,19 +38,19 @@ func countingSort(nums: inout [Int]) {
|
||||
}
|
||||
// 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
|
||||
// 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
|
||||
for i in stride(from: 0, to: m, by: 1) {
|
||||
for i in 0 ..< m {
|
||||
counter[i + 1] += counter[i]
|
||||
}
|
||||
// 4. 倒序遍历 nums ,将各元素填入结果数组 res
|
||||
// 初始化数组 res 用于记录结果
|
||||
var res = Array(repeating: 0, count: nums.count)
|
||||
for i in stride(from: nums.count - 1, through: 0, by: -1) {
|
||||
for i in nums.indices.reversed() {
|
||||
let num = nums[i]
|
||||
res[counter[num] - 1] = num // 将 num 放置到对应索引处
|
||||
counter[num] -= 1 // 令前缀和自减 1 ,得到下次放置 num 的索引
|
||||
}
|
||||
// 使用结果数组 res 覆盖原数组 nums
|
||||
for i in stride(from: 0, to: nums.count, by: 1) {
|
||||
for i in nums.indices {
|
||||
nums[i] = res[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func heapSort(nums: inout [Int]) {
|
||||
siftDown(nums: &nums, n: nums.count, i: i)
|
||||
}
|
||||
// 从堆中提取最大元素,循环 n-1 轮
|
||||
for i in stride(from: nums.count - 1, to: 0, by: -1) {
|
||||
for i in nums.indices.dropFirst().reversed() {
|
||||
// 交换根节点与最右叶节点(交换首元素与尾元素)
|
||||
nums.swapAt(0, i)
|
||||
// 以根节点为起点,从顶至底进行堆化
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* 插入排序 */
|
||||
func insertionSort(nums: inout [Int]) {
|
||||
// 外循环:已排序区间为 [0, i-1]
|
||||
for i in stride(from: 1, to: nums.count, by: 1) {
|
||||
for i in nums.indices.dropFirst() {
|
||||
let base = nums[i]
|
||||
var j = i - 1
|
||||
// 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
|
||||
|
||||
@@ -16,12 +16,11 @@ func merge(nums: inout [Int], left: Int, mid: Int, right: Int) {
|
||||
if nums[i] <= nums[j] {
|
||||
tmp[k] = nums[i]
|
||||
i += 1
|
||||
k += 1
|
||||
} else {
|
||||
tmp[k] = nums[j]
|
||||
j += 1
|
||||
k += 1
|
||||
}
|
||||
k += 1
|
||||
}
|
||||
// 将左子数组和右子数组的剩余元素复制到临时数组中
|
||||
while i <= mid {
|
||||
@@ -60,7 +59,7 @@ enum MergeSort {
|
||||
static func main() {
|
||||
/* 归并排序 */
|
||||
var nums = [7, 3, 2, 6, 0, 1, 5, 4]
|
||||
mergeSort(nums: &nums, left: 0, right: nums.count - 1)
|
||||
mergeSort(nums: &nums, left: nums.startIndex, right: nums.endIndex - 1)
|
||||
print("归并排序完成后 nums = \(nums)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,6 @@
|
||||
* Author: nuomi1 (nuomi1@qq.com)
|
||||
*/
|
||||
|
||||
/* 元素交换 */
|
||||
func swap(nums: inout [Int], i: Int, j: Int) {
|
||||
let tmp = nums[i]
|
||||
nums[i] = nums[j]
|
||||
nums[j] = tmp
|
||||
}
|
||||
|
||||
/* 快速排序类 */
|
||||
/* 哨兵划分 */
|
||||
func partition(nums: inout [Int], left: Int, right: Int) -> Int {
|
||||
@@ -24,9 +17,9 @@ func partition(nums: inout [Int], left: Int, right: Int) -> Int {
|
||||
while i < j, nums[i] <= nums[left] {
|
||||
i += 1 // 从左向右找首个大于基准数的元素
|
||||
}
|
||||
swap(nums: &nums, i: i, j: j) // 交换这两个元素
|
||||
nums.swapAt(i, j) // 交换这两个元素
|
||||
}
|
||||
swap(nums: &nums, i: i, j: left) // 将基准数交换至两子数组的分界线
|
||||
nums.swapAt(i, left) // 将基准数交换至两子数组的分界线
|
||||
return i // 返回基准数的索引
|
||||
}
|
||||
|
||||
@@ -43,7 +36,6 @@ func quickSort(nums: inout [Int], left: Int, right: Int) {
|
||||
quickSort(nums: &nums, left: pivot + 1, right: right)
|
||||
}
|
||||
|
||||
|
||||
/* 快速排序类(中位基准数优化) */
|
||||
/* 选取三个候选元素的中位数 */
|
||||
func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
|
||||
@@ -51,12 +43,12 @@ func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
|
||||
let m = nums[mid]
|
||||
let r = nums[right]
|
||||
if (l <= m && m <= r) || (r <= m && m <= l) {
|
||||
return mid; // m 在 l 和 r 之间
|
||||
return mid // m 在 l 和 r 之间
|
||||
}
|
||||
if (m <= l && l <= r) || (r <= l && l <= m) {
|
||||
return left; // l 在 m 和 r 之间
|
||||
return left // l 在 m 和 r 之间
|
||||
}
|
||||
return right;
|
||||
return right
|
||||
}
|
||||
|
||||
/* 哨兵划分(三数取中值) */
|
||||
@@ -64,7 +56,7 @@ func partitionMedian(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.swapAt(left, med)
|
||||
return partition(nums: &nums, left: left, right: right)
|
||||
}
|
||||
|
||||
@@ -81,7 +73,6 @@ func quickSortMedian(nums: inout [Int], left: Int, right: Int) {
|
||||
quickSortMedian(nums: &nums, left: pivot + 1, right: right)
|
||||
}
|
||||
|
||||
|
||||
/* 快速排序(尾递归优化) */
|
||||
func quickSortTailCall(nums: inout [Int], left: Int, right: Int) {
|
||||
var left = left
|
||||
@@ -107,17 +98,17 @@ enum QuickSort {
|
||||
static func main() {
|
||||
/* 快速排序 */
|
||||
var nums = [2, 4, 1, 0, 3, 5]
|
||||
quickSort(nums: &nums, left: 0, right: nums.count - 1)
|
||||
quickSort(nums: &nums, left: nums.startIndex, right: nums.endIndex - 1)
|
||||
print("快速排序完成后 nums = \(nums)")
|
||||
|
||||
/* 快速排序(中位基准数优化) */
|
||||
var nums1 = [2, 4, 1, 0, 3, 5]
|
||||
quickSortMedian(nums: &nums1, left: 0, right: nums1.count - 1)
|
||||
quickSortMedian(nums: &nums1, left: nums1.startIndex, right: nums1.endIndex - 1)
|
||||
print("快速排序(中位基准数优化)完成后 nums1 = \(nums1)")
|
||||
|
||||
/* 快速排序(尾递归优化) */
|
||||
var nums2 = [2, 4, 1, 0, 3, 5]
|
||||
quickSortTailCall(nums: &nums2, left: 0, right: nums2.count - 1)
|
||||
quickSortTailCall(nums: &nums2, left: nums2.startIndex, right: nums2.endIndex - 1)
|
||||
print("快速排序(尾递归优化)完成后 nums2 = \(nums2)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ func digit(num: Int, exp: Int) -> Int {
|
||||
func countingSortDigit(nums: inout [Int], exp: Int) {
|
||||
// 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
|
||||
var counter = Array(repeating: 0, count: 10)
|
||||
let n = nums.count
|
||||
// 统计 0~9 各数字的出现次数
|
||||
for i in nums.indices {
|
||||
let d = digit(num: nums[i], exp: exp) // 获取 nums[i] 第 k 位,记为 d
|
||||
@@ -25,8 +24,8 @@ func countingSortDigit(nums: inout [Int], exp: Int) {
|
||||
counter[i] += counter[i - 1]
|
||||
}
|
||||
// 倒序遍历,根据桶内统计结果,将各元素填入 res
|
||||
var res = Array(repeating: 0, count: n)
|
||||
for i in stride(from: n - 1, through: 0, by: -1) {
|
||||
var res = Array(repeating: 0, count: nums.count)
|
||||
for i in nums.indices.reversed() {
|
||||
let d = digit(num: nums[i], exp: exp)
|
||||
let j = counter[d] - 1 // 获取 d 在数组中的索引 j
|
||||
res[j] = nums[i] // 将当前元素填入索引 j
|
||||
@@ -62,8 +61,18 @@ enum RadixSort {
|
||||
/* Driver Code */
|
||||
static func main() {
|
||||
// 基数排序
|
||||
var nums = [10546151, 35663510, 42865989, 34862445, 81883077,
|
||||
88906420, 72429244, 30524779, 82060337, 63832996]
|
||||
var nums = [
|
||||
10_546_151,
|
||||
35_663_510,
|
||||
42_865_989,
|
||||
34_862_445,
|
||||
81_883_077,
|
||||
88_906_420,
|
||||
72_429_244,
|
||||
30_524_779,
|
||||
82_060_337,
|
||||
63_832_996,
|
||||
]
|
||||
radixSort(nums: &nums)
|
||||
print("基数排序完成后 nums = \(nums)")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user