diff --git a/codes/rust/chapter_sorting/heap_sort.rs b/codes/rust/chapter_sorting/heap_sort.rs new file mode 100644 index 000000000..bc8ac16cb --- /dev/null +++ b/codes/rust/chapter_sorting/heap_sort.rs @@ -0,0 +1,58 @@ +/* + * File: heap_sort.rs + * Created Time: 2023-07-04 + * Author: night-cruise (2586447362@qq.com) + */ + +include!("../include/include.rs"); + +/* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */ +fn sift_down(nums: &mut [i32], n: usize, mut i: usize) { + loop { + // 判断节点 i, l, r 中值最大的节点,记为 ma + let l = 2 * i + 1; + let r = 2 * i + 2; + let mut 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; + } + // 交换两节点 + let temp = nums[i]; + nums[i] = nums[ma]; + nums[ma] = temp; + // 循环向下堆化 + i = ma; + } +} + +/* 堆排序 */ +fn heap_sort(nums: &mut [i32]) { + // 建堆操作:堆化除叶节点以外的其他所有节点 + for i in (0..=nums.len() / 2 - 1).rev() { + sift_down(nums, nums.len(), i); + } + // 从堆中提取最大元素,循环 n-1 轮 + for i in (1..=nums.len() - 1).rev() { + // 交换根节点与最右叶节点(即交换首元素与尾元素) + let tmp = nums[0]; + nums[0] = nums[i]; + nums[i] = tmp; + // 以根节点为起点,从顶至底进行堆化 + sift_down(nums, i, 0); + } +} + +/* Driver Code */ +fn main() { + let mut nums = [4, 1, 3, 1, 5, 2]; + heap_sort(&mut nums); + print!("堆排序完成后 nums = "); + print_util::print_array(&nums); +} \ No newline at end of file