This commit is contained in:
2026-07-20 19:57:25 +08:00
parent 4fa78d4c00
commit 124ad9afdf
26 changed files with 2715 additions and 5 deletions
+37 -5
View File
@@ -174,8 +174,7 @@ func HeapSort(nums []int) {
return
}
// siftDown:在 [0, end] 范围内把 nums[i] 下沉到正确位置
var siftDown func(i, end int)
siftDown = func(i, end int) {
siftDown := func(i, end int) {
for 2*i+1 <= end {
l, r := 2*i+1, 2*i+2
largest := i
@@ -206,7 +205,39 @@ func HeapSort(nums []int) {
// ShellSort 希尔排序:按递减步长分组做插入排序,最后步长为 1 退化为插入排序。
// 平均约 O(n^1.3),非稳定。代码短,比插入排序在乱序数据上快很多。
func ShellSort(nums []int) {
// TODO: 你来写
gap := len(nums)
for gap > 1 {
gap /= 2
for i := 0; i < len(nums); i++ {
// 插入排序
for j := 1; j*gap+i < len(nums); j++ {
for k := j; k > 0; k-- {
if nums[k*gap+i] < nums[(k-1)*gap+i] {
nums[k*gap+i], nums[(k-1)*gap+i] = nums[(k-1)*gap+i], nums[k*gap+i]
} else {
break
}
}
}
}
}
}
// ShellSortStandard 是更常见的希尔排序写法:不显式遍历每一个分组,
// 而是让 j 每次减 gap,使其天然只在 nums[i%gap] 这一组内移动。
// 相比 ShellSort 的交换式插入,这里先保存 key、再右移元素,能减少写入次数。
func ShellSortStandard(nums []int) {
for gap := len(nums) / 2; gap > 0; gap /= 2 {
for i := gap; i < len(nums); i++ {
key := nums[i]
j := i
for j-gap >= 0 && key < nums[j-gap] {
nums[j] = nums[j-gap]
j -= gap
}
nums[j] = key
}
}
}
// CountingSort 计数排序:元素为 [0, k] 整数,统计频次后前缀和定位。
@@ -271,9 +302,10 @@ func TestSortAlgos(t *testing.T) {
// {"SelectionSort", SelectionSort},
// {"InsertionSort", InsertionSort},
// {"MergeSort", MergeSort},
{"HeapSort", HeapSort},
{"BucketSort", BucketSort},
// {"HeapSort", HeapSort},
// {"BucketSort", BucketSort},
// {"ShellSort", ShellSort},
{"ShellSortStandard", ShellSortStandard},
// {"CountingSort", CountingSort},
}
for _, s := range sorters {