diff --git a/codes/swift/Package.swift b/codes/swift/Package.swift index ac3c564f5..df043d701 100644 --- a/codes/swift/Package.swift +++ b/codes/swift/Package.swift @@ -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"]), diff --git a/codes/swift/chapter_sorting/heap_sort.swift b/codes/swift/chapter_sorting/heap_sort.swift new file mode 100644 index 000000000..c81f2d9de --- /dev/null +++ b/codes/swift/chapter_sorting/heap_sort.swift @@ -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)") + } +}