package main
import (
"fmt"
"math/rand"
"time"
)
func QuickSort(arr []int) {
quickSort(arr, 0, len(arr)-1)
}
func quickSort(arr []int, l, r int) {
stdIndex := partition2(arr, l, r)
if stdIndex < 0 {
return
}
quickSort(arr, l, stdIndex-1)
quickSort(arr, stdIndex+1, r)
}
func FindK(arr []int, k int) {
findK(arr, 0, len(arr)-1, k-1)
}
func findK(arr []int, l, r, k int) {
stdIndex := partition(arr, l, r)
if stdIndex < 0 {
return
}
if stdIndex == k {
return
} else if stdIndex > k {
findK(arr, l, stdIndex-1, k)
} else {
findK(arr, stdIndex+1, r, k)
}
}
func partition(arr []int, l, r int) int {
if l >= r {
return -1
}
ll, rr := l, r
stdIsLeft := true
for ll < rr {
if stdIsLeft {
if arr[rr] > arr[ll] {
rr--
} else {
arr[ll], arr[rr] = arr[rr], arr[ll]
ll++
stdIsLeft = false
}
} else {
if arr[ll] < arr[rr] {
ll++
} else {
arr[ll], arr[rr] = arr[rr], arr[ll]
rr--
stdIsLeft = true
}
}
}
if stdIsLeft {
return ll
} else {
return rr
}
}
func partition2(arr []int, l, r int) int {
if l >= r {
return -1
}
mid(arr, l, r)
ll, rr := l+1, r
for ll <= rr {
if arr[rr] > arr[l] {
rr--
} else {
arr[ll], arr[rr] = arr[rr], arr[ll]
ll++
}
}
arr[l], arr[rr] = arr[rr], arr[l]
return rr
}
func mid(arr []int, l, r int) {
midIndex := (l + r) / 2
if arr[midIndex] > arr[l] && arr[midIndex] < arr[r] || arr[midIndex] < arr[l] && arr[midIndex] > arr[r] {
arr[midIndex], arr[l] = arr[l], arr[midIndex]
return
}
if arr[r] > arr[l] && arr[r] < arr[midIndex] || arr[r] < arr[l] && arr[r] > arr[midIndex] {
arr[r], arr[l] = arr[l], arr[r]
}
}
func main() {
rand.Seed(time.Now().UnixNano())
num := 200
arr := make([]int, num)
copy_arr := make([]int, num)
for i := 0; i < num; i++ {
arr[i] = rand.Intn(1000000)
}
copy(copy_arr, arr)
QuickSort(arr)
fmt.Println(arr)
nnn := 20
fmt.Println(arr[:nnn])
FindK(copy_arr, nnn)
fmt.Println(copy_arr[:nnn])
}