Submitted in niuke network through, corresponding topic
/ / the entry
func Sort(a []int) {
l := len(a)
if l < 2 {
return
}
sort(a, 0, l- 1, getMaxDepth(l))
}
// Control the maximum depth of recursion
func getMaxDepth(n int) int {
var depth int
for i := n; i > 0; i >>= 1 {
depth++
}
return 2*depth
}
// recursive call
func sort(a []int, low, high, depth int) {
// high-low+1 > 12
if high-low > 11 {
if depth == 0 {
// Use heap sort instead for maximum recursion depth
heapSort(a, low, high)
} else {
depth--
pivotIndex := partition(a, low, high)
sort(a, low, pivotIndex- 1, depth)
sort(a, pivotIndex+1, high, depth)
}
} else {
// Use insertion sort between cells
insertionSort(a, low, high)
}
}
func heapSort(a []int, low, high int) {
// The loop variable used when processing the heap is evaluated based on 0
// The index for reading and writing elements of array A is calculated based on low
// l := high-low+1
// end := l-1
end := high-low
for i := (end- 1) /2; i >= 0; i-- {
heapify(a, i, end, low)
}
for i := end; i > 0; i-- {
a[low], a[low+i] = a[low+i], a[low] // a[low] = a[low+0]
heapify(a, 0, i- 1, low)
}
}
// Adjust downward
func heapify(a []int, b, e, low int) {
// The loop variable used when processing the heap is calculated based on b
// The index for reading and writing elements of array A is calculated based on low
p := b
pv := a[low+p]
for {
child := 2*p + 1
if child > e {
break
}
if child+1 <= e && a[low+child+1] > a[low+child] {
child++
}
if pv >= a[low+child] {
break
}
a[low+p] = a[low+child]
p = child
}
a[low+p] = pv
}
func insertionSort(a []int, low, high int) {
for i := low+1; i <= high; i++ {
n := a[i]
j := i- 1
for j >= low && a[j] > n {
a[j+1] = a[j]
j--
}
a[j+1] = n
}
}
// Range index range [low, high]
// Binary segmentation or "hole filling"
// Return value: the index position where pivot is placed after shard is complete
func partition(a []int, low, high int) int {
selectPivot(a, low, high) // Place pivot on low index
pivot := a[low] // The first pit
for low < high {
for low < high && a[high] >= pivot {
high--
}
a[low] = a[high]
for low < high && a[low] <= pivot {
low++
}
a[high] = a[low]
}
a[low] = pivot
return low
}
// Place the selected pivot element on the low index
func selectPivot(a []int, low, high int) {
l := high-low+1
mid := low + (high-low)>>1
// l <= 40
// if l > 40
if l > 40 {
seg := l/8
medianOfThree(a, low, low+seg, low+2*seg)
medianOfThree(a, mid, mid-seg, mid+seg)
medianOfThree(a, high, high-seg, high2 -*seg)
}
medianOfThree(a, low, mid, high)
}
// select * from i1; // select * from i1; // Select * from i1
func medianOfThree(a []int, i1, i0, i2 int) {
if a[i1] > a[i2] {
a[i1], a[i2] = a[i2], a[i1]
}
if a[i0] > a[i2] {
a[i0], a[i2] = a[i2], a[i0]
}
if a[i1] < a[i0] {
a[i1], a[i0] = a[i0], a[i1]
}
}
Copy the code