feat: add Swift codes for heap_sort article (#520)

This commit is contained in:
nuomi1
2023-05-29 12:20:32 +08:00
committed by GitHub
parent 8bed60f0d7
commit 56a4385202
2 changed files with 57 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ let package = Package(
.executable(name: "insertion_sort", targets: ["insertion_sort"]),
.executable(name: "quick_sort", targets: ["quick_sort"]),
.executable(name: "merge_sort", targets: ["merge_sort"]),
.executable(name: "heap_sort", targets: ["heap_sort"]),
.executable(name: "bucket_sort", targets: ["bucket_sort"]),
.executable(name: "counting_sort", targets: ["counting_sort"]),
.executable(name: "radix_sort", targets: ["radix_sort"]),
@@ -115,6 +116,7 @@ let package = Package(
.executableTarget(name: "insertion_sort", path: "chapter_sorting", sources: ["insertion_sort.swift"]),
.executableTarget(name: "quick_sort", path: "chapter_sorting", sources: ["quick_sort.swift"]),
.executableTarget(name: "merge_sort", path: "chapter_sorting", sources: ["merge_sort.swift"]),
.executableTarget(name: "heap_sort", path: "chapter_sorting", sources: ["heap_sort.swift"]),
.executableTarget(name: "bucket_sort", path: "chapter_sorting", sources: ["bucket_sort.swift"]),
.executableTarget(name: "counting_sort", path: "chapter_sorting", sources: ["counting_sort.swift"]),
.executableTarget(name: "radix_sort", path: "chapter_sorting", sources: ["radix_sort.swift"]),

View File

@@ -0,0 +1,55 @@
/**
* File: heap_sort.swift
* Created Time: 2023-05-28
* Author: nuomi1 (nuomi1@qq.com)
*/
/* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
func siftDown(nums: inout [Int], n: Int, i: Int) {
var i = i
while true {
// 判断节点 i, l, r 中值最大的节点,记为 ma
let l = 2 * i + 1
let r = 2 * i + 2
var ma = i
if l < n, nums[l] > nums[ma] {
ma = l
}
if r < n, nums[r] > nums[ma] {
ma = r
}
// 若节点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
if ma == i {
break
}
// 交换两节点
nums.swapAt(i, ma)
// 循环向下堆化
i = ma
}
}
/* 堆排序 */
func heapSort(nums: inout [Int]) {
// 建堆操作:堆化除叶节点以外的其他所有节点
for i in stride(from: nums.count / 2 - 1, through: 0, by: -1) {
siftDown(nums: &nums, n: nums.count, i: i)
}
// 从堆中提取最大元素,循环 n-1 轮
for i in stride(from: nums.count - 1, to: 0, by: -1) {
// 交换根节点与最右叶节点(即交换首元素与尾元素)
nums.swapAt(0, i)
// 以根节点为起点,从顶至底进行堆化
siftDown(nums: &nums, n: i, i: 0)
}
}
@main
enum HeapSort {
/* Driver Code */
static func main() {
var nums = [4, 1, 3, 1, 5, 2]
heapSort(nums: &nums)
print("堆排序完成后 nums = \(nums)")
}
}